
/**
 @file sys_dmps_api.c

 @date 2009-10-19

 @version v2.0

 The file define APIs of chip of sys layer
*/
/****************************************************************************
 *
 * Header Files
 *
 ****************************************************************************/
#include "ctc_error.h"
#include "sys_usw_common.h"
#include "sys_usw_port.h"
#include "sys_usw_mac.h"
#include "sys_usw_datapath.h"
#include "sys_usw_flexe.h"
#include "sys_usw_peri.h"
#include "sys_usw_dmps.h"
#include "sys_usw_dmps_db.h"
#include "sys_usw_phy.h"
#include "sys_usw_register.h"
#include "drv_api.h"
#include "sys_usw_interrupt.h"
#include "sys_usw_mcu.h"
#include "usw/include/drv_common.h"
#include "usw/include/sys/sys_usw_serdes_api.h"

/****************************************************************************
 *
 * Global and static
 *
 *****************************************************************************/

uint32 g_port_link_mode = LINK_MODE_PCS_PMA;

extern int32 _sys_usw_mac_get_cl37_an_remote_status(uint8 lchip, uint16 lport, uint32 auto_neg_mode, uint32* p_speed, uint32* p_link);
extern void _sys_usw_mac_show_cl73_ability(uint32 value);
int32 _sys_usw_dmps_get_fec(uint8 lchip, uint16 lport, uint32* p_value);
int32 sys_usw_dmps_get_direction_property(uint8 lchip, uint32 gport, ctc_port_direction_property_t port_prop, ctc_direction_t dir, uint32* p_value);
int32 _sys_usw_dmps_get_loopback_en(uint8 lchip, uint16 lport, void* p_lpbk);

/****************************************************************************
 *
 * Function
 *
 *****************************************************************************/
int32
sys_usw_dmps_gport_map_to_lport_with_check(uint8 lchip, uint32 gport, uint16* p_lport)
{
    uint8 gchip = SYS_MAP_CTC_GPORT_TO_GCHIP(gport);
    uint16 lport = 0;
    uint8 idx = 0;
    uint8 is_network = 0;
    CTC_PTR_VALID_CHECK(p_lport);

    SYS_GLOBAL_CHIPID_CHECK(gchip);
    if (FALSE == sys_usw_chip_is_local(lchip, gchip))
    {
        return CTC_E_INVALID_CHIP_ID;
    }
    lport = CTC_MAP_GPORT_TO_LPORT(gport);
    if ((lport >= MCHIP_CAP(SYS_CAP_PER_SLICE_PORT_NUM) * MCHIP_CAP(SYS_CAP_LOCAL_SLICE_NUM)) || CTC_IS_LINKAGG_PORT(gport)
        || (CTC_IS_CPU_PORT(gport) && (DRV_IS_DUET2(lchip) || DRV_IS_TSINGMA(lchip))))
    {
        return CTC_E_INVALID_PORT;
    }

    if (CTC_IS_CPU_PORT(gport))
    {
        idx = gport & 0xf;
        if(MCHIP_DMPS(lchip)->cpumac_get_lport_info_by_inner_idx)
        {
            CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->cpumac_get_lport_info_by_inner_idx(lchip,idx,&lport,&is_network));
        }
    }
    else
    {
        lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(lport);
    }
    *p_lport = lport;

    return CTC_E_NONE;
}

uint32
sys_usw_dmps_get_speed_from_serdes_info(uint8 if_mode, uint8 fec_type, uint8 ocs)
{
    uint32 serdes_speed = 0;
    uint32 serdes_speed_basic[CTC_CHIP_MAX_SERDES_MODE][SYS_DMPS_FEC_TYPE_MAX] = {
        /*NONE,                  RS528                   RS544                  RS272                 FC2112(BASER-FEC)       RS544Int              RS272Int    */
        {SERDES_SPEED_0G,        SERDES_SPEED_0G,        SERDES_SPEED_0G,       SERDES_SPEED_0G,      SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_NONE_MODE*/     
        {SERDES_SPEED_10_3125G,  SERDES_SPEED_0G,        SERDES_SPEED_0G,       SERDES_SPEED_0G,      SERDES_SPEED_10_3125G,  SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_XFI_MODE*/      
        {SERDES_SPEED_1_25G,     SERDES_SPEED_0G,        SERDES_SPEED_0G,       SERDES_SPEED_0G,      SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_SGMII_MODE*/    
        {SERDES_SPEED_0G,        SERDES_SPEED_0G,        SERDES_SPEED_0G,       SERDES_SPEED_0G,      SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_XSGMII_MODE*/   
        {SERDES_SPEED_1_25G,     SERDES_SPEED_0G,        SERDES_SPEED_0G,       SERDES_SPEED_0G,      SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_QSGMII_MODE*/   
        {SERDES_SPEED_3_125G,    SERDES_SPEED_0G,        SERDES_SPEED_0G,       SERDES_SPEED_0G,      SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_XAUI_MODE*/     
        {SERDES_SPEED_3_125G,    SERDES_SPEED_0G,        SERDES_SPEED_0G,       SERDES_SPEED_0G,      SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_DXAUI_MODE*/    
        {SERDES_SPEED_10_3125G,  SERDES_SPEED_0G,        SERDES_SPEED_0G,       SERDES_SPEED_0G,      SERDES_SPEED_10_3125G,  SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_XLG_MODE*/      
        {SERDES_SPEED_25_78125G, SERDES_SPEED_25_78125G, SERDES_SPEED_26_5625G, SERDES_SPEED_0G,      SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_CG_MODE*/       
        {SERDES_SPEED_3_125G,    SERDES_SPEED_0G,        SERDES_SPEED_0G,       SERDES_SPEED_0G,      SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_2DOT5G_MODE*/   
        {SERDES_SPEED_10_3125G,  SERDES_SPEED_0G,        SERDES_SPEED_0G,       SERDES_SPEED_0G,      SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_USXGMII0_MODE*/ 
        {SERDES_SPEED_10_3125G,  SERDES_SPEED_0G,        SERDES_SPEED_0G,       SERDES_SPEED_0G,      SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_USXGMII1_MODE*/ 
        {SERDES_SPEED_10_3125G,  SERDES_SPEED_0G,        SERDES_SPEED_0G,       SERDES_SPEED_0G,      SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_USXGMII2_MODE*/ 
        {SERDES_SPEED_25_78125G, SERDES_SPEED_25_78125G, SERDES_SPEED_0G,       SERDES_SPEED_0G,      SERDES_SPEED_25_78125G, SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_XXVG_MODE*/     
        {SERDES_SPEED_25_78125G, SERDES_SPEED_25_78125G, SERDES_SPEED_26_5625G, SERDES_SPEED_0G,      SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_LG_MODE*/       
        {SERDES_SPEED_1_25G,     SERDES_SPEED_0G,        SERDES_SPEED_0G,       SERDES_SPEED_0G,      SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_100BASEFX_MODE*/
        {SERDES_SPEED_51_5625G,  SERDES_SPEED_51_5625G,  SERDES_SPEED_53_125G,  SERDES_SPEED_53_125G, SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_LG_R1_MODE*/    
        {SERDES_SPEED_51_5625G,  SERDES_SPEED_51_5625G,  SERDES_SPEED_53_125G,  SERDES_SPEED_53_125G, SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_CG_R2_MODE*/    
        {SERDES_SPEED_0G,        SERDES_SPEED_0G,        SERDES_SPEED_53_125G,  SERDES_SPEED_53_125G, SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_CCG_R4_MODE*/
        {SERDES_SPEED_0G,        SERDES_SPEED_0G,        SERDES_SPEED_53_125G,  SERDES_SPEED_53_125G, SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_CDG_R8_MODE*/
        {SERDES_SPEED_20_625G,   SERDES_SPEED_20_625G,   SERDES_SPEED_26_5625G, SERDES_SPEED_0G,      SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_XLG_R2_MODE*/
        {SERDES_SPEED_0G,        SERDES_SPEED_0G,        SERDES_SPEED_106_25G,  SERDES_SPEED_106_25G, SERDES_SPEED_0G,        SERDES_SPEED_106_25G, SERDES_SPEED_106_25G},/*CTC_CHIP_SERDES_CG_R1_MODE*/
        {SERDES_SPEED_0G,        SERDES_SPEED_0G,        SERDES_SPEED_106_25G,  SERDES_SPEED_106_25G, SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_CCG_R2_MODE*/ 
        {SERDES_SPEED_0G,        SERDES_SPEED_0G,        SERDES_SPEED_106_25G,  SERDES_SPEED_106_25G, SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_CDG_R4_MODE*/
        {SERDES_SPEED_0G,        SERDES_SPEED_0G,        SERDES_SPEED_106_25G,  SERDES_SPEED_106_25G, SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_DCCCG_R8_MODE*/
        {SERDES_SPEED_0G,        SERDES_SPEED_0G,        SERDES_SPEED_0G,       SERDES_SPEED_0G,      SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_PHY_MODE*/ 
        {SERDES_SPEED_0G,        SERDES_SPEED_0G,        SERDES_SPEED_0G,       SERDES_SPEED_0G,      SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_RGMII_MODE*/
        {SERDES_SPEED_42_5G,     SERDES_SPEED_42_5G,     SERDES_SPEED_42_5G,    SERDES_SPEED_42_5G,   SERDES_SPEED_0G,        SERDES_SPEED_0G,      SERDES_SPEED_0G},     /*CTC_CHIP_SERDES_XLG_R1_MODE*/ 
    };

    uint32 serdes_speed_ocs[CTC_CHIP_MAX_SERDES_OCS_MODE] =
    {
        /*speed value(Ksym/s)  ovserclock mode*/
        SERDES_SPEED_0G,                /*CTC_CHIP_SERDES_OCS_MODE_NONE    */
        SERDES_SPEED_11_40625G,             /*CTC_CHIP_SERDES_OCS_MODE_11_06G  */
        SERDES_SPEED_12_5G,             /*CTC_CHIP_SERDES_OCS_MODE_12_12G  */
        SERDES_SPEED_12_96875G,            /*CTC_CHIP_SERDES_OCS_MODE_12_58G  */
        SERDES_SPEED_28_125G,           /*CTC_CHIP_SERDES_OCS_MODE_27_27G  */
        SERDES_SPEED_10_9375G,             /*CTC_CHIP_SERDES_OCS_MODE_10_6G   */
        SERDES_SPEED_26_5625G,            /*CTC_CHIP_SERDES_OCS_MODE_26_56G  */
        SERDES_SPEED_27_34375G,            /*CTC_CHIP_SERDES_OCS_MODE_26_52G  */
        SERDES_SPEED_27_78125G,            /*CTC_CHIP_SERDES_OCS_MODE_26_9G   */
        SERDES_SPEED_37_5G,             /*CTC_CHIP_SERDES_OCS_MODE_36_36G  */
        SERDES_SPEED_39_0625G,            /*CTC_CHIP_SERDES_OCS_MODE_36_76G  */
        SERDES_SPEED_11_40625G,             /*CTC_CHIP_SERDES_OCS_MODE_11_06G11*/
        SERDES_SPEED_12_96875G,            /*CTC_CHIP_SERDES_OCS_MODE_12_58G12*/
        SERDES_SPEED_53_125G,           /*CTC_CHIP_SERDES_OCS_MODE_51_56G  */
        SERDES_SPEED_56_25G,            /*CTC_CHIP_SERDES_OCS_MODE_52_71G  */
        SERDES_SPEED_20_625G,            /*CTC_CHIP_SERDES_OCS_MODE_20_625G */
        SERDES_SPEED_106_25G,           /*CTC_CHIP_SERDES_OCS_MODE_103_12G */
        SERDES_SPEED_112_5G,            /*CTC_CHIP_SERDES_OCS_MODE_105_42G */
    };

    if(CTC_CHIP_SERDES_OCS_MODE_NONE != ocs)
    {
        serdes_speed = (CTC_CHIP_MAX_SERDES_OCS_MODE > ocs) ? serdes_speed_ocs[ocs] : SERDES_SPEED_0G;
    }
    else
    {
        serdes_speed = ((CTC_CHIP_MAX_SERDES_MODE > if_mode) && (SYS_DMPS_FEC_TYPE_MAX > fec_type)) ? serdes_speed_basic[if_mode][fec_type] : SERDES_SPEED_0G;
    }

    return serdes_speed;
}

#ifdef EMULATION_ENV
uint8 g_source_mac_en = 0;
int32
sys_usw_mac_set_mac_en_emu(uint8 lchip, uint32 mac_id, uint8 mac_enable)
{
    uint32 cmd = 0;
    uint32 portid = mac_id;
    ds_t data_entry = {0};
    uint32 field_value;
    uint32 bit_offset=0;
    uint32 index = 0;

    if (!g_source_mac_en)
    {
        return 0;
    }

    if(portid >= 160)
    {
        lchip += 4;
        portid = portid - 160;
    }

    bit_offset = (portid % 8);
    index = DRV_INS(portid / 8, 0);

    if(mac_enable)
    {
        cmd = DRV_IOR(McPcs800Reset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));
        field_value = GetMcPcs800Reset(V, cfgSoftResetTxChanBmp_f, data_entry);
        CTC_BIT_UNSET(field_value, bit_offset);
        SetMcPcs800Reset(V, cfgSoftResetTxChanBmp_f, data_entry, field_value);
        cmd = DRV_IOW(McPcs800Reset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));

        cmd = DRV_IOR(McMacTxSoftReset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));
        field_value = GetMcMacTxSoftReset(V, cfgMcMacMiiTxSoftReset_f, data_entry);
        CTC_BIT_UNSET(field_value, bit_offset);
        SetMcMacTxSoftReset(V, cfgMcMacMiiTxSoftReset_f, data_entry, field_value);
        cmd = DRV_IOW(McMacTxSoftReset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));


        cmd = DRV_IOR(McMacMacTxCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));
        field_value = 1;
        switch(bit_offset)
        {
            case 0: SetMcMacMacTxCfg(V, cfgMcMacMacTx_0_cfgMcMacTxSendEn_f, data_entry, field_value);break;
            case 1: SetMcMacMacTxCfg(V, cfgMcMacMacTx_1_cfgMcMacTxSendEn_f, data_entry, field_value);break;
            case 2: SetMcMacMacTxCfg(V, cfgMcMacMacTx_2_cfgMcMacTxSendEn_f, data_entry, field_value);break;
            case 3: SetMcMacMacTxCfg(V, cfgMcMacMacTx_3_cfgMcMacTxSendEn_f, data_entry, field_value);break;
            case 4: SetMcMacMacTxCfg(V, cfgMcMacMacTx_4_cfgMcMacTxSendEn_f, data_entry, field_value);break;
            case 5: SetMcMacMacTxCfg(V, cfgMcMacMacTx_5_cfgMcMacTxSendEn_f, data_entry, field_value);break;
            case 6: SetMcMacMacTxCfg(V, cfgMcMacMacTx_6_cfgMcMacTxSendEn_f, data_entry, field_value);break;
            case 7: SetMcMacMacTxCfg(V, cfgMcMacMacTx_7_cfgMcMacTxSendEn_f, data_entry, field_value);break;
        }
        cmd = DRV_IOW(McMacMacTxCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));

        cmd = DRV_IOR(McMacRxSoftReset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));
        field_value = GetMcMacRxSoftReset(V, cfgMcMacMacRxSoftReset_f, data_entry);
        CTC_BIT_UNSET(field_value, bit_offset);
        SetMcMacRxSoftReset(V, cfgMcMacMacRxSoftReset_f, data_entry, field_value);
        field_value = GetMcMacRxSoftReset(V, cfgMcMacMiiRxSoftReset_f, data_entry);
        CTC_BIT_UNSET(field_value, bit_offset);
        SetMcMacRxSoftReset(V, cfgMcMacMiiRxSoftReset_f, data_entry, field_value);
        cmd = DRV_IOW(McMacRxSoftReset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));

        cmd = DRV_IOR(McPcs800Reset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));
        field_value = GetMcPcs800Reset(V, cfgSoftResetRxChanBmp_f, data_entry);
        CTC_BIT_UNSET(field_value, bit_offset);
        SetMcPcs800Reset(V, cfgSoftResetRxChanBmp_f, data_entry, field_value);
        cmd = DRV_IOW(McPcs800Reset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));
    }
    else
    {
        cmd = DRV_IOR(McPcs800Reset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));
        field_value = GetMcPcs800Reset(V, cfgSoftResetRxChanBmp_f, data_entry);
        CTC_BIT_SET(field_value, bit_offset);
        SetMcPcs800Reset(V, cfgSoftResetRxChanBmp_f, data_entry, field_value);
        cmd = DRV_IOW(McPcs800Reset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));

        cmd = DRV_IOR(McMacRxSoftReset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));
        field_value = GetMcMacRxSoftReset(V, cfgMcMacMacRxSoftReset_f, data_entry);
        CTC_BIT_SET(field_value, bit_offset);
        SetMcMacRxSoftReset(V, cfgMcMacMacRxSoftReset_f, data_entry, field_value);
        field_value = GetMcMacRxSoftReset(V, cfgMcMacMiiRxSoftReset_f, data_entry);
        CTC_BIT_SET(field_value, bit_offset);
        SetMcMacRxSoftReset(V, cfgMcMacMiiRxSoftReset_f, data_entry, field_value);
        cmd = DRV_IOW(McMacRxSoftReset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));

        cmd = DRV_IOR(McMacMacTxCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));
        field_value = 0;
        switch(bit_offset)
        {
            case 0: SetMcMacMacTxCfg(V, cfgMcMacMacTx_0_cfgMcMacTxSendEn_f, data_entry, field_value);break;
            case 1: SetMcMacMacTxCfg(V, cfgMcMacMacTx_1_cfgMcMacTxSendEn_f, data_entry, field_value);break;
            case 2: SetMcMacMacTxCfg(V, cfgMcMacMacTx_2_cfgMcMacTxSendEn_f, data_entry, field_value);break;
            case 3: SetMcMacMacTxCfg(V, cfgMcMacMacTx_3_cfgMcMacTxSendEn_f, data_entry, field_value);break;
            case 4: SetMcMacMacTxCfg(V, cfgMcMacMacTx_4_cfgMcMacTxSendEn_f, data_entry, field_value);break;
            case 5: SetMcMacMacTxCfg(V, cfgMcMacMacTx_5_cfgMcMacTxSendEn_f, data_entry, field_value);break;
            case 6: SetMcMacMacTxCfg(V, cfgMcMacMacTx_6_cfgMcMacTxSendEn_f, data_entry, field_value);break;
            case 7: SetMcMacMacTxCfg(V, cfgMcMacMacTx_7_cfgMcMacTxSendEn_f, data_entry, field_value);break;
        }
        cmd = DRV_IOW(McMacMacTxCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));

        cmd = DRV_IOR(McMacTxSoftReset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));
        field_value = GetMcMacTxSoftReset(V, cfgMcMacMiiTxSoftReset_f, data_entry);
        CTC_BIT_SET(field_value, bit_offset);
        SetMcMacTxSoftReset(V, cfgMcMacMiiTxSoftReset_f, data_entry, field_value);
        cmd = DRV_IOW(McMacTxSoftReset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));

        cmd = DRV_IOR(McPcs800Reset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));
        field_value = GetMcPcs800Reset(V, cfgSoftResetTxChanBmp_f, data_entry);
        CTC_BIT_SET(field_value, bit_offset);
        SetMcPcs800Reset(V, cfgSoftResetTxChanBmp_f, data_entry, field_value);
        cmd = DRV_IOW(McPcs800Reset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));

        cmd = DRV_IOR(McPcs800InterruptNormal_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));
        field_value = 0;
        #if 0
        switch(bit_offset)
        {
            case 0: DRV_IOW_FIELD(lchip, McPcs800InterruptNormal_t, McPcs800InterruptNormal_intrTxAsyncFifoUnderrunLane0_f, &field_value, data_entry);break;
            case 1: DRV_IOW_FIELD(lchip, McPcs800InterruptNormal_t, McPcs800InterruptNormal_intrTxAsyncFifoUnderrunLane1_f, &field_value, data_entry);break;
            case 2: DRV_IOW_FIELD(lchip, McPcs800InterruptNormal_t, McPcs800InterruptNormal_intrTxAsyncFifoUnderrunLane2_f, &field_value, data_entry);break;
            case 3: DRV_IOW_FIELD(lchip, McPcs800InterruptNormal_t, McPcs800InterruptNormal_intrTxAsyncFifoUnderrunLane3_f, &field_value, data_entry);break;
            case 4: DRV_IOW_FIELD(lchip, McPcs800InterruptNormal_t, McPcs800InterruptNormal_intrTxAsyncFifoUnderrunLane4_f, &field_value, data_entry);break;
            case 5: DRV_IOW_FIELD(lchip, McPcs800InterruptNormal_t, McPcs800InterruptNormal_intrTxAsyncFifoUnderrunLane5_f, &field_value, data_entry);break;
            case 6: DRV_IOW_FIELD(lchip, McPcs800InterruptNormal_t, McPcs800InterruptNormal_intrTxAsyncFifoUnderrunLane6_f, &field_value, data_entry);break;
            case 7: DRV_IOW_FIELD(lchip, McPcs800InterruptNormal_t, McPcs800InterruptNormal_intrTxAsyncFifoUnderrunLane7_f, &field_value, data_entry);break;
        }
        #endif
        cmd = DRV_IOW(McPcs800InterruptNormal_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), data_entry));
    }
    return CTC_E_NONE;
}
#endif

int32
sys_usw_dmps_mac_set_interface_mode(uint8 lchip, uint16 lport, ctc_port_if_mode_t* if_mode)
{
    int32 ret = 0;

    if(MCHIP_DMPS(lchip)->mac_set_interface_mode)
    {
        ret = MCHIP_DMPS(lchip)->mac_set_interface_mode(lchip, lport, if_mode);
    }
    else return CTC_E_INVALID_PTR;

    return ret;
}

int32
sys_usw_dmps_get_interface_mode(uint8 lchip, uint16 lport, ctc_port_if_mode_t* if_mode)
{
    CTC_ERROR_RETURN(sys_usw_mac_get_interface_type(lchip, lport, if_mode));

    return CTC_E_NONE;
}

int32
sys_usw_dmps_get_mac_capability(uint8 lchip, uint16 lport, ctc_port_capability_type_t type, void* p_value)
{
    int32 ret = 0;

    if(MCHIP_DMPS(lchip)->mac_get_capability)
    {
        ret = MCHIP_DMPS(lchip)->mac_get_capability(lchip, lport, type, p_value);
    }
    else return CTC_E_INVALID_PTR;

    return ret;
}

int32
sys_usw_dmps_set_mac_capability(uint8 lchip, uint16 lport, ctc_port_capability_type_t type, uint32 value)
{
    int32 ret = 0;

    if(MCHIP_DMPS(lchip)->mac_set_capability)
    {
        ret = MCHIP_DMPS(lchip)->mac_set_capability(lchip, lport, type, value);
    }
    else return CTC_E_INVALID_PTR;

    return ret;
}

int32
sys_usw_mac_self_check_print(void* p_self_check_info)
{
    int8   space_length         = 0;
    uint8  idx                  = 0;
    int16  coefficient[CTC_CHIP_FFE_PARAM_NUM] = {0};
    uint32 invalid_2bit         = 3;
    uint32 invalid_4bit         = 15;
    uint32 invalid_5bit         = 31;
    char* speed[SYS_PORT_SPEED_MAX] = {
        "1G",   //SYS_PORT_SPEED_1G
        "100M", //SYS_PORT_SPEED_100M
        "10M",  //SYS_PORT_SPEED_10M
        "2.5G", //SYS_PORT_SPEED_2G5
        "10G",  //SYS_PORT_SPEED_10G
        "20G",  //SYS_PORT_SPEED_20G
        "40G",  //SYS_PORT_SPEED_40G
        "100G", //SYS_PORT_SPEED_100G
        "5G",   //SYS_PORT_SPEED_5G
        "25G",  //SYS_PORT_SPEED_25G
        "50G",  //SYS_PORT_SPEED_50G
        "200G", //SYS_PORT_SPEED_200G
        "400G", //SYS_PORT_SPEED_400G
        "800G", //SYS_PORT_SPEED_800G
        "300G"  //SYS_PORT_SPEED_300G
    };
    char* itf[CTC_PORT_IF_MAX_TYPE] = {
        "-"           , //CTC_PORT_IF_NONE
        "SGMII"       , //CTC_PORT_IF_SGMII
        "2500X"       , //CTC_PORT_IF_2500X
        "QSGMII"      , //CTC_PORT_IF_QSGMII
        "USXGMII-S"   , //CTC_PORT_IF_USXGMII_S
        "USXGMII-M2G5", //CTC_PORT_IF_USXGMII_M2G5
        "USXGMII-M5G" , //CTC_PORT_IF_USXGMII_M5G
        "XAUI"        , //CTC_PORT_IF_XAUI
        "D-XAUI"      , //CTC_PORT_IF_DXAUI
        "XFI"         , //CTC_PORT_IF_XFI
        "KR"          , //CTC_PORT_IF_KR
        "CR"          , //CTC_PORT_IF_CR
        "KR2"         , //CTC_PORT_IF_KR2
        "CR2"         , //CTC_PORT_IF_CR2
        "KR4"         , //CTC_PORT_IF_KR4
        "CR4"         , //CTC_PORT_IF_CR4
        "FX"          , //CTC_PORT_IF_FX
        "KR8"         , //CTC_PORT_IF_KR8
        "CR8"         , //CTC_PORT_IF_CR8
        "FLEXE"       , //CTC_PORT_IF_FLEXE
    };
    char* fec[SYS_DMPS_FEC_TYPE_MAX] = {
        "None",          //SYS_DMPS_FEC_TYPE_NONE
        "RS(528,514)",   //SYS_DMPS_FEC_TYPE_RS528
        "RS(544,514)",   //SYS_DMPS_FEC_TYPE_RS544
        "RS(272,257)",   //SYS_DMPS_FEC_TYPE_RS272
        "Base-R FEC",    //SYS_DMPS_FEC_TYPE_FC2112
        "RS(544,514)INT",//SYS_DMPS_FEC_TYPE_RS544INT
        "RS(272,257)INT" //SYS_DMPS_FEC_TYPE_RS272INT
    };
    char* cl37_an_mode[SYS_DMPS_MAX_PCS_MODULE][SYS_DMPS_CL37_ANMODE_MAX] =
    {
       {"1000BaseX mode", "SGMII PHY to MAC mode", "SGMII MAC to PHY mode", "-", "-", "-", "-", "-"},     /*SharedPcs , SGMII & 2500BASE-X*/
       {"1000BaseX mode", "USXGMII PHY to MAC mode", "USXGMII MAC to PHY mode", "-", "-", "-", "-", "-"}, /*UsxgmiiPcs, USXGMII*/
       {"1000BaseX mode", "USGMII PHY to MAC mode", "USGMII MAC to PHY mode", "SGMII PHY to MAC mode",    /*UsgmiiPcs , O-USGMII & Q-USGMII*/
        "SGMII MAC to PHY mode", "QSGMII PHY to MAC mode", "QSGMII MAC to PHY mode", "Configured by SDK"}
    };
    char* lane_speed[SERDES_SPEED_MAX] = {
        "0       ",
        "1.25    ",
        "3.125   ",
        "10.3125 ",
        "11.40625",
        "12.5    ",
        "12.96875",
        "10.9375 ",
        "20.625  ",
        "25.78125",
        "28.125  ",
        "26.5625 ",
        "27.34375",
        "27.78125",
        "37.5    ",
        "39.0625 ",
        "51.5625 ",
        "53.125  ",
        "56.25   ",
        "103.125 ",
        "106.25  ",
        "112.5   ",
        "42.5    "
    };
    char* lt_stat[SYS_PORT_CL72_NUM] = {
        "Disable", //SYS_PORT_CL72_DISABLE
        "Running", //SYS_PORT_CL72_PROGRESS
        "Fail",    //SYS_PORT_CL72_FAIL
        "OK",      //SYS_PORT_CL72_OK
    };
    char* lpbk_mode[] = {
        "Internal",
        "External",
        "Local",
        "PCS",
        "None"
    };
    char* anlt_sm[] = {
        "Idle",
        "AN Running",
        "LT Running",
        "ANLT Done",
        "Link Up",
    };
    char* prbs_mode[] = {
        "PRBS7+",
        "PRBS7-",
        "PRBS15+",
        "PRBS15-",
        "PRBS23+",
        "PRBS23-",
        "PRBS31+",
        "PRBS31-",
    };

    sys_dmps_mac_self_check_info_t* self_check_info = (sys_dmps_mac_self_check_info_t*)p_self_check_info;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Chip Info\n");
    SELF_CHECK_PRINT_FORMAT("Chip Freq", self_check_info->chip_frequency, SYS_DMPS_INVALID_U16,\
        self_check_info->chip_frequency, SELF_CHECK_STR_NO_USE);

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Port Map\n");
    SELF_CHECK_PRINT_FORMAT("LPort", self_check_info->lport, SYS_DMPS_INVALID_U16, \
        self_check_info->lport, SELF_CHECK_STR_NO_USE);
    SELF_CHECK_PRINT_FORMAT("Datapath Channel", self_check_info->chan_id, SYS_DMPS_INVALID_U16,\
        self_check_info->chan_id, SELF_CHECK_STR_NO_USE);
    SELF_CHECK_PRINT_FORMAT("MAC ID", self_check_info->mac_id, SYS_DMPS_INVALID_U16,\
        self_check_info->mac_id, SELF_CHECK_STR_NO_USE);
    SELF_CHECK_PRINT_FORMAT("PCS ID", self_check_info->pcs_id, SYS_DMPS_INVALID_U16,\
        self_check_info->pcs_id, SELF_CHECK_STR_NO_USE);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "    %-24s: ", "Logical-SerDes");
    for(idx = 0; idx < self_check_info->serdes_num; idx++)
    {
        if(SYS_DMPS_INVALID_U16 == self_check_info->logical_serdes[idx])
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-3s ", "-");
        }
        else
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-3u ", self_check_info->logical_serdes[idx]);
        }
    }
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "    %-24s: ", "Physical-SerDes");
    for(idx = 0; idx < self_check_info->serdes_num; idx++)
    {
        if(SYS_DMPS_INVALID_U16 == self_check_info->physical_serdes[idx])
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-3s ", "-");
        }
        else
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-3u ", self_check_info->physical_serdes[idx]);
        }
    }
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "    %-24s: ", "User-SerDes");
    for(idx = 0; idx < self_check_info->serdes_num; idx++)
    {
        if(SYS_DMPS_INVALID_U16 == self_check_info->user_serdes[idx])
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-3s ", "-");
        }
        else
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-3u ", self_check_info->user_serdes[idx]);
        }
    }
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Port Config\n");
    SELF_CHECK_PRINT_FORMAT("Speed", self_check_info->speed_mode, SYS_DMPS_INVALID_U8,\
        SELF_CHECK_VALUE_NO_USE, speed[self_check_info->speed_mode]);
    SELF_CHECK_PRINT_FORMAT("Interface", self_check_info->if_type, SYS_DMPS_INVALID_U8,\
        SELF_CHECK_VALUE_NO_USE, itf[self_check_info->if_type]);
    SELF_CHECK_PRINT_FORMAT("FEC", self_check_info->fec_val, SYS_DMPS_INVALID_U32,\
        SELF_CHECK_VALUE_NO_USE, fec[self_check_info->fec_val]);
    SELF_CHECK_PRINT_FORMAT("Auto-Neg", self_check_info->an_en, invalid_2bit,\
        SELF_CHECK_VALUE_NO_USE, (0 == self_check_info->an_en) ? "Disable" : "Enable");
    SELF_CHECK_PRINT_FORMAT("MAC-EN", self_check_info->mac_en, invalid_2bit,\
        SELF_CHECK_VALUE_NO_USE, (0 == self_check_info->mac_en) ? "Disable" : "Enable");
    SELF_CHECK_PRINT_FORMAT("MAC RX Packet", self_check_info->mac_rx_pkt_en, invalid_2bit,\
        SELF_CHECK_VALUE_NO_USE, (0 == self_check_info->mac_rx_pkt_en) ? "Disable" : "Enable");
    SELF_CHECK_PRINT_FORMAT("MAC TX Packet", self_check_info->mac_tx_pkt_en, invalid_2bit,\
        SELF_CHECK_VALUE_NO_USE, (0 == self_check_info->mac_tx_pkt_en) ? "Disable" : "Enable");
    SELF_CHECK_PRINT_FORMAT("Preamble", self_check_info->preamble_length, invalid_5bit,\
        self_check_info->preamble_length, SELF_CHECK_STR_NO_USE);
    SELF_CHECK_PRINT_FORMAT("IPG", self_check_info->ipg_length, invalid_5bit,\
        self_check_info->ipg_length, SELF_CHECK_STR_NO_USE);
    SELF_CHECK_PRINT_FORMAT("SuperG2-EN", self_check_info->higig2_en, invalid_2bit,\
        SELF_CHECK_VALUE_NO_USE, self_check_info->higig2_en ? "Enable" : "Disable");
    SELF_CHECK_PRINT_FORMAT("Padding", self_check_info->padding_en, invalid_2bit,\
        SELF_CHECK_VALUE_NO_USE, self_check_info->padding_en ? "Enable" : "Disable");
    SELF_CHECK_PRINT_FORMAT("Check-CRC", self_check_info->check_crc_en, invalid_2bit,\
        SELF_CHECK_VALUE_NO_USE, self_check_info->check_crc_en ? "Enable" : "Disable");
    SELF_CHECK_PRINT_FORMAT("Strip-CRC", self_check_info->strip_crc_en, invalid_2bit,\
        SELF_CHECK_VALUE_NO_USE, self_check_info->strip_crc_en ? "Enable" : "Disable");
    SELF_CHECK_PRINT_FORMAT("Append-CRC", self_check_info->append_crc_en, invalid_2bit,\
        SELF_CHECK_VALUE_NO_USE, self_check_info->append_crc_en ? "Enable" : "Disable");
    SELF_CHECK_PRINT_FORMAT("Append-TOD", self_check_info->append_tod_en, invalid_2bit,\
        SELF_CHECK_VALUE_NO_USE, self_check_info->append_tod_en ? "Enable" : "Disable");
    if(SYS_MAC_IS_MODE_SUPPORT_CL37(self_check_info->if_mode))
    {
        SELF_CHECK_PRINT_FORMAT("Parallel detect", self_check_info->parallel_detect_en, invalid_2bit,\
            SELF_CHECK_VALUE_NO_USE, self_check_info->parallel_detect_en ? "Enable" : "Disable");
        SELF_CHECK_PRINT_FORMAT("Autoneg Mode", self_check_info->an_mode, invalid_4bit,\
            SELF_CHECK_VALUE_NO_USE, cl37_an_mode[self_check_info->pcs_module][self_check_info->an_mode]);
    }
    if(SYS_MAC_IS_MODE_SUPPORT_CL73(self_check_info->if_mode))
    {
        if(SYS_DMPS_INVALID_U32 == self_check_info->cl73_local_ability)
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "    %-24s: %s\n", "Port cl73 ability", "-");
        }
        else
        {
            _sys_usw_mac_show_cl73_ability(self_check_info->cl73_local_ability);
        }
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "    %-24s: ", "cl73 fec");
        if(SYS_DMPS_INVALID_U32 == self_check_info->cl73_fec)
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s ", "-");
        }
        else
        {
            if(CTC_PORT_FEC_TYPE_NONE == self_check_info->cl73_fec)
            {
                SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s ", "NONE");
            }
            if((1 << CTC_PORT_FEC_TYPE_RS) & self_check_info->cl73_fec)
            {
                SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s ", "RS-FEC");
            }
            if((1 << CTC_PORT_FEC_TYPE_BASER) & self_check_info->cl73_fec)
            {
                SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s ", "BASE-R FEC");
            }
        }
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");
        SELF_CHECK_PRINT_FORMAT("Autoneg Mode", self_check_info->an_mode, invalid_4bit, SELF_CHECK_VALUE_NO_USE,\
            (0 == self_check_info->an_mode) ? "Default mode" : "OverClock Mode");
    }
    SELF_CHECK_PRINT_FORMAT("pcs link intr", self_check_info->pcs_link_intr_en, invalid_2bit,\
        SELF_CHECK_VALUE_NO_USE, self_check_info->pcs_link_intr_en ? "Enable" : "Disable");
    SELF_CHECK_PRINT_FORMAT("unidir enable", self_check_info->unidir_en, invalid_2bit,\
        SELF_CHECK_VALUE_NO_USE, self_check_info->unidir_en ? "Enable" : "Disable");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "    %-24s: %ums\n", "Link filter", self_check_info->link_filter_length);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "    %-24s: %ums\n", "Fault filter", self_check_info->fault_filter_length);
    SELF_CHECK_PRINT_FORMAT("TX force fault", self_check_info->tx_force_fault, invalid_2bit,\
        SELF_CHECK_VALUE_NO_USE, self_check_info->tx_force_fault ? "Enable" : "Disable");
    SELF_CHECK_PRINT_FORMAT("PCS RX reset", self_check_info->pcs_rx_rst, invalid_2bit,\
        self_check_info->pcs_rx_rst, SELF_CHECK_STR_NO_USE);
    SELF_CHECK_PRINT_FORMAT("PCS TX reset", self_check_info->pcs_tx_rst, invalid_2bit,\
        self_check_info->pcs_tx_rst, SELF_CHECK_STR_NO_USE);
    SELF_CHECK_PRINT_FORMAT("MII RX reset", self_check_info->mii_rx_rst, invalid_2bit,\
        self_check_info->mii_rx_rst, SELF_CHECK_STR_NO_USE);
    SELF_CHECK_PRINT_FORMAT("MII TX reset", self_check_info->mii_tx_rst, invalid_2bit,\
        self_check_info->mii_tx_rst, SELF_CHECK_STR_NO_USE);

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "MAC Status\n");
    SELF_CHECK_PRINT_FORMAT("Link mode", self_check_info->link_mode, SYS_DMPS_INVALID_U32, SELF_CHECK_VALUE_NO_USE,\
        (self_check_info->link_mode == LINK_MODE_PCS_PMA) ? "PCS-PMA" : ((self_check_info->link_mode == LINK_MODE_STDALONE)\
        ? "STANDALONE" : "-"));
    SELF_CHECK_PRINT_FORMAT("Link FSM", self_check_info->link_fsm, SYS_DMPS_INVALID_U32,\
        self_check_info->link_fsm, SELF_CHECK_STR_NO_USE);
    SELF_CHECK_PRINT_FORMAT("Link status", self_check_info->link_status, invalid_2bit, SELF_CHECK_VALUE_NO_USE,\
        (0 == self_check_info->link_status) ? "down" : "up");
    SELF_CHECK_PRINT_FORMAT("Link status raw", self_check_info->link_status_raw, invalid_2bit, SELF_CHECK_VALUE_NO_USE,\
        (0 == self_check_info->link_status_raw) ? "down" : "up");
    SELF_CHECK_PRINT_FORMAT("Local fault", self_check_info->local_fault, invalid_2bit,\
        self_check_info->local_fault, SELF_CHECK_STR_NO_USE);
    SELF_CHECK_PRINT_FORMAT("Remote fault", self_check_info->remote_fault, invalid_2bit,\
        self_check_info->remote_fault, SELF_CHECK_STR_NO_USE);
    SELF_CHECK_PRINT_FORMAT("Link fault", self_check_info->link_fault, invalid_2bit,\
        self_check_info->link_fault, SELF_CHECK_STR_NO_USE);

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "PCS Status\n");
    SELF_CHECK_PRINT_FORMAT("pcs_sync", self_check_info->pcs_sync, invalid_2bit,\
        self_check_info->pcs_sync, SELF_CHECK_STR_NO_USE);
    SELF_CHECK_PRINT_FORMAT("hi_ber", self_check_info->hi_ber, invalid_2bit,\
        self_check_info->hi_ber, SELF_CHECK_STR_NO_USE);
    SELF_CHECK_PRINT_FORMAT("RxBlockLock", self_check_info->rx_block_lock, invalid_2bit, SELF_CHECK_VALUE_NO_USE,\
        (self_check_info->rx_block_lock != 0) ? "ok" : "fail");
    SELF_CHECK_PRINT_FORMAT("RxAmLock", self_check_info->rx_am_lock, invalid_2bit, SELF_CHECK_VALUE_NO_USE,\
        (self_check_info->rx_am_lock != 0) ? "ok" : "fail");
    SELF_CHECK_PRINT_FORMAT("RxCwmLock", self_check_info->rx_cwm_lock, invalid_2bit, SELF_CHECK_VALUE_NO_USE,\
        (self_check_info->rx_cwm_lock != 0) ? "ok" : "fail");
    SELF_CHECK_PRINT_FORMAT("Code Error Cnt", self_check_info->code_err_cnt, SYS_DMPS_INVALID_U16,\
        self_check_info->code_err_cnt, SELF_CHECK_STR_NO_USE);
    SELF_CHECK_PRINT_FORMAT("Bad Ber Cnt", self_check_info->bad_ber_cnt, SYS_DMPS_INVALID_U16,\
        self_check_info->bad_ber_cnt, SELF_CHECK_STR_NO_USE);
    SELF_CHECK_PRINT_FORMAT("Error Block Cnt", self_check_info->err_blk_cnt, SYS_DMPS_INVALID_U16,\
        self_check_info->err_blk_cnt, SELF_CHECK_STR_NO_USE);
    SELF_CHECK_PRINT_FORMAT("Bip Error Cnt", self_check_info->bip_err_cnt, SYS_DMPS_INVALID_U16,\
        self_check_info->bip_err_cnt, SELF_CHECK_STR_NO_USE);

    if(self_check_info->fec_val)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "FEC Status\n");
        SELF_CHECK_PRINT_FORMAT("hi_ser", self_check_info->hi_ser, invalid_2bit,\
            self_check_info->hi_ser, SELF_CHECK_STR_NO_USE);
        SELF_CHECK_PRINT_FORMAT("FecAmLock", self_check_info->fec_am_lock, invalid_2bit, SELF_CHECK_VALUE_NO_USE,\
            (self_check_info->fec_am_lock != 0) ? "ok" : "fail");
        SELF_CHECK_PRINT_FORMAT("XgFecLock", self_check_info->xgfec_lock, invalid_2bit, SELF_CHECK_VALUE_NO_USE,\
            (self_check_info->xgfec_lock != 0) ? "ok" : "fail");
        SELF_CHECK_PRINT_FORMAT("RsFecLock", self_check_info->rsfec_lock, invalid_2bit, SELF_CHECK_VALUE_NO_USE,\
            (self_check_info->rsfec_lock != 0) ? "ok" : "fail");
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "    %-32s: %u\n", "CW/Blk cnt of corrected Error", self_check_info->correct_cnt);
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "    %-32s: %u\n", "CW/Blk cnt of uncorrected Error", self_check_info->uncorrect_cnt);
    }

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "SerDes Cfg/Status\n");

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Psd    Index BaudRate(G)     SigDet  ForceSigDet  PllLock(Group/TX/RX)\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    for(idx = 0; idx < self_check_info->serdes_num; idx++)
    {
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%-6u ", self_check_info->physical_serdes[idx], "%-6s ",
            SELF_CHECK_STR_NO_USE, self_check_info->physical_serdes[idx], SYS_DMPS_INVALID_U16);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%-5u ", idx, "%-5s ", SELF_CHECK_STR_NO_USE, idx,\
            SYS_DMPS_INVALID_U8);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%-15u ", SELF_CHECK_VALUE_NO_USE, "%-15s ",\
            lane_speed[self_check_info->serdes_info[idx].lane_speed], self_check_info->serdes_info[idx].lane_speed, SYS_DMPS_INVALID_U8);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%-7u ", self_check_info->serdes_info[idx].sig_det, "%-7s ",\
            SELF_CHECK_STR_NO_USE, self_check_info->serdes_info[idx].sig_det, invalid_2bit);
        if((invalid_2bit == self_check_info->serdes_info[idx].force_sig_det_val) || \
            (invalid_2bit == self_check_info->serdes_info[idx].force_sig_det_en))
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-12s ", "-");
        }
        else if(0 == self_check_info->serdes_info[idx].force_sig_det_en)
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-12s ", "No Force");
        }
        else
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-12s ",\
                self_check_info->serdes_info[idx].force_sig_det_val ? "Force 1" : "Force 0");
        }
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u/", SELF_CHECK_VALUE_NO_USE, "%s/",\
            self_check_info->serdes_info[idx].group_pll_lock ? "LOCK" : "UNLOCK", self_check_info->serdes_info[idx].group_pll_lock, invalid_2bit);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u/", SELF_CHECK_VALUE_NO_USE, "%s/",\
            self_check_info->serdes_info[idx].lane_tx_pll_lock ? "LOCK" : "UNLOCK", self_check_info->serdes_info[idx].lane_tx_pll_lock, invalid_2bit);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u\n", SELF_CHECK_VALUE_NO_USE, "%s\n",\
            self_check_info->serdes_info[idx].lane_rx_pll_lock ? "LOCK" : "UNLOCK", self_check_info->serdes_info[idx].lane_rx_pll_lock, invalid_2bit);
    }

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "             CDRLock         RxReady CDRDetectEn  Eye(Height/Width)   \n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    for(idx = 0; idx < self_check_info->serdes_num; idx++)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "             ");
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%-15u ", SELF_CHECK_VALUE_NO_USE, "%-15s ",\
            self_check_info->serdes_info[idx].cdr_lock ? "LOCK" : "UNLOCK", self_check_info->serdes_info[idx].cdr_lock, invalid_2bit);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%-7u ", self_check_info->serdes_info[idx].rx_rdy, "%-7s ",\
            SELF_CHECK_STR_NO_USE, self_check_info->serdes_info[idx].rx_rdy, invalid_2bit);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%-12u ", SELF_CHECK_VALUE_NO_USE, "%-12s ",\
            self_check_info->serdes_info[idx].cdr_det_en ? "Enable" : "Disable", self_check_info->serdes_info[idx].cdr_det_en, invalid_2bit);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u/", self_check_info->serdes_info[idx].eye_height, "%s/",\
            SELF_CHECK_STR_NO_USE, self_check_info->serdes_info[idx].eye_height, SYS_DMPS_INVALID_U32);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u\n", self_check_info->serdes_info[idx].eye_width, "%s\n",\
            SELF_CHECK_STR_NO_USE, self_check_info->serdes_info[idx].eye_width, SYS_DMPS_INVALID_U32);
    }

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "             SigDetThrd(mV)  SNR     Loopback     Polarity(TX/RX)     \n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    for(idx = 0; idx < self_check_info->serdes_num; idx++)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "             ");
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%-15u ", self_check_info->serdes_info[idx].sig_det_thrd , "%-15s ",\
            SELF_CHECK_STR_NO_USE, self_check_info->serdes_info[idx].sig_det_thrd, SYS_DMPS_INVALID_U32);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%-7u ", self_check_info->serdes_info[idx].snr, "%-7s ",\
            SELF_CHECK_STR_NO_USE, self_check_info->serdes_info[idx].snr, SYS_DMPS_INVALID_U32);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%-12u ", SELF_CHECK_VALUE_NO_USE, "%-12s ",\
            lpbk_mode[self_check_info->serdes_info[idx].lpbk_mode], self_check_info->serdes_info[idx].lpbk_mode, SYS_DMPS_INVALID_U8);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u/", SELF_CHECK_VALUE_NO_USE, "%s/",\
            self_check_info->serdes_info[idx].tx_poly ? "INVERSE" : "NORMAL", self_check_info->serdes_info[idx].tx_poly, invalid_2bit);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u\n", SELF_CHECK_VALUE_NO_USE, "%s\n",\
            self_check_info->serdes_info[idx].rx_poly ? "INVERSE" : "NORMAL", self_check_info->serdes_info[idx].rx_poly, invalid_2bit);
    }

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "             LaneEn(TX/RX)           ANLTSM       TrainStat(TX/RX)    \n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    for(idx = 0; idx < self_check_info->serdes_num; idx++)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "             ");
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u/", SELF_CHECK_VALUE_NO_USE, "%s/",\
            self_check_info->serdes_info[idx].tx_lane_en ? "Enable" : "Disable", self_check_info->serdes_info[idx].tx_lane_en, invalid_2bit);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u", SELF_CHECK_VALUE_NO_USE, "%s",\
            self_check_info->serdes_info[idx].rx_lane_en ? "Enable" : "Disable", self_check_info->serdes_info[idx].rx_lane_en, invalid_2bit);
        space_length = sal_strlen("LaneEn(TX/RX)           ");
        SELF_CHECK_SPACE_PRINT_CALC(space_length, self_check_info->serdes_info[idx].tx_lane_en, invalid_2bit, SELF_CHECK_VALUE_NO_USE,\
            self_check_info->serdes_info[idx].tx_lane_en ? "Enable" : "Disable");
        space_length -= sal_strlen("/");
        SELF_CHECK_SPACE_PRINT_CALC(space_length, self_check_info->serdes_info[idx].rx_lane_en, invalid_2bit, SELF_CHECK_VALUE_NO_USE,\
            self_check_info->serdes_info[idx].rx_lane_en ? "Enable" : "Disable");
        SELF_CHECK_SPACE_PRINT(space_length);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%-12u ", SELF_CHECK_VALUE_NO_USE, "%-12s ",\
            anlt_sm[self_check_info->serdes_info[idx].anlt_state], self_check_info->serdes_info[idx].anlt_state, SYS_DMPS_INVALID_U8);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u/", SELF_CHECK_VALUE_NO_USE, "%s/",\
            lt_stat[self_check_info->serdes_info[idx].tx_train_stat], self_check_info->serdes_info[idx].tx_train_stat, SYS_DMPS_INVALID_U8);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u\n", SELF_CHECK_VALUE_NO_USE, "%s\n",\
            lt_stat[self_check_info->serdes_info[idx].rx_train_stat], self_check_info->serdes_info[idx].rx_train_stat, SYS_DMPS_INVALID_U8);
    }

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "             FwVersion               FwStat       PowerUp(Group/TX/RX)\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    for(idx = 0; idx < self_check_info->serdes_num; idx++)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "             ");
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u.", self_check_info->serdes_info[idx].fw_ver.v_major, "%s.",\
            SELF_CHECK_STR_NO_USE, self_check_info->serdes_info[idx].fw_ver.v_major, SYS_DMPS_INVALID_U32);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u.", self_check_info->serdes_info[idx].fw_ver.v_minor, "%s.",\
            SELF_CHECK_STR_NO_USE, self_check_info->serdes_info[idx].fw_ver.v_minor, SYS_DMPS_INVALID_U32);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u.", self_check_info->serdes_info[idx].fw_ver.v_patch, "%s.",\
            SELF_CHECK_STR_NO_USE, self_check_info->serdes_info[idx].fw_ver.v_patch, SYS_DMPS_INVALID_U32);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u", self_check_info->serdes_info[idx].fw_ver.v_build, "%s",\
            SELF_CHECK_STR_NO_USE, self_check_info->serdes_info[idx].fw_ver.v_build, SYS_DMPS_INVALID_U32);
        space_length = sal_strlen("FwVersion               ");
        SELF_CHECK_SPACE_PRINT_CALC(space_length, self_check_info->serdes_info[idx].fw_ver.v_major, SYS_DMPS_INVALID_U32,\
            self_check_info->serdes_info[idx].fw_ver.v_major, SELF_CHECK_STR_NO_USE);
        space_length -= sal_strlen(".");
        SELF_CHECK_SPACE_PRINT_CALC(space_length, self_check_info->serdes_info[idx].fw_ver.v_minor, SYS_DMPS_INVALID_U32,\
            self_check_info->serdes_info[idx].fw_ver.v_minor, SELF_CHECK_STR_NO_USE);
        space_length -= sal_strlen(".");
        SELF_CHECK_SPACE_PRINT_CALC(space_length, self_check_info->serdes_info[idx].fw_ver.v_patch, SYS_DMPS_INVALID_U32,\
            self_check_info->serdes_info[idx].fw_ver.v_patch, SELF_CHECK_STR_NO_USE);
        space_length -= sal_strlen(".");
        SELF_CHECK_SPACE_PRINT_CALC(space_length, self_check_info->serdes_info[idx].fw_ver.v_build, SYS_DMPS_INVALID_U32,\
            self_check_info->serdes_info[idx].fw_ver.v_build, SELF_CHECK_STR_NO_USE);
        SELF_CHECK_SPACE_PRINT(space_length);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%-12u ", SELF_CHECK_VALUE_NO_USE , "%-12s ",\
            self_check_info->serdes_info[idx].fw_stat ? "Runing" : "Stop", self_check_info->serdes_info[idx].fw_stat, SYS_DMPS_INVALID_U8);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u/", SELF_CHECK_VALUE_NO_USE, "%s/",\
            self_check_info->serdes_info[idx].group_power_on ? "On" : "Off", self_check_info->serdes_info[idx].group_power_on, invalid_2bit);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u/", SELF_CHECK_VALUE_NO_USE, "%s/",\
            self_check_info->serdes_info[idx].lane_tx_power_on ? "On" : "Off", self_check_info->serdes_info[idx].lane_tx_power_on, invalid_2bit);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u\n", SELF_CHECK_VALUE_NO_USE, "%s\n",\
            self_check_info->serdes_info[idx].lane_rx_power_on ? "On" : "Off", self_check_info->serdes_info[idx].lane_rx_power_on, invalid_2bit);
    }

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "             TxPRBS(En/Patt)         RxPRBS(En/Patt/Cnt)              \n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    for(idx = 0; idx < self_check_info->serdes_num; idx++)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "             ");
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u/", SELF_CHECK_VALUE_NO_USE, "%s/",\
            self_check_info->serdes_info[idx].tx_prbs_en ? "Enable" : "Disable", self_check_info->serdes_info[idx].tx_prbs_en, invalid_2bit);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u", SELF_CHECK_VALUE_NO_USE, "%s",\
            prbs_mode[self_check_info->serdes_info[idx].tx_prbs_pat], self_check_info->serdes_info[idx].tx_prbs_pat, SYS_DMPS_INVALID_U8);
        space_length = sal_strlen("TxPRBS(En/Patt)         ");
        SELF_CHECK_SPACE_PRINT_CALC(space_length, self_check_info->serdes_info[idx].tx_prbs_en, invalid_2bit, SELF_CHECK_VALUE_NO_USE,\
            self_check_info->serdes_info[idx].tx_prbs_en ? "Enable" : "Disable");
        space_length -= sal_strlen("/");
        SELF_CHECK_SPACE_PRINT_CALC(space_length, self_check_info->serdes_info[idx].tx_prbs_pat, SYS_DMPS_INVALID_U8, SELF_CHECK_VALUE_NO_USE,\
            prbs_mode[self_check_info->serdes_info[idx].tx_prbs_pat]);
        SELF_CHECK_SPACE_PRINT(space_length);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u/", SELF_CHECK_VALUE_NO_USE, "%s/",\
            self_check_info->serdes_info[idx].rx_prbs_en ? "Enable" : "Disable", self_check_info->serdes_info[idx].rx_prbs_en, invalid_2bit);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u/", SELF_CHECK_VALUE_NO_USE, "%s/",\
            prbs_mode[self_check_info->serdes_info[idx].rx_prbs_pat], self_check_info->serdes_info[idx].rx_prbs_pat, SYS_DMPS_INVALID_U8);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u\n", self_check_info->serdes_info[idx].rx_prbs_cnt, "%s\n",\
            SELF_CHECK_STR_NO_USE, self_check_info->serdes_info[idx].rx_prbs_cnt, SYS_DMPS_INVALID_U32);
    }

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "             TxEq                                                     \n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    for(idx = 0; idx < self_check_info->serdes_num; idx++)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "             ");
        sal_memcpy(coefficient, self_check_info->serdes_info[idx].tx_eq.coefficient, sizeof(coefficient));
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("C0:%d  ", coefficient[0], "C0:%s  ",\
            SELF_CHECK_STR_NO_USE, coefficient[0], SYS_DMPS_INVALID_U16);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("C1:%d  ", coefficient[1], "C1:%s  ",\
            SELF_CHECK_STR_NO_USE, coefficient[1], SYS_DMPS_INVALID_U16);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("C2:%d  ", coefficient[2], "C2:%s  ",\
            SELF_CHECK_STR_NO_USE, coefficient[2], SYS_DMPS_INVALID_U16);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("C3:%d  ", coefficient[3], "C3:%s  ",\
            SELF_CHECK_STR_NO_USE, coefficient[3], SYS_DMPS_INVALID_U16);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("C4:%d  ", coefficient[4], "C4:%s  ",\
            SELF_CHECK_STR_NO_USE, coefficient[4], SYS_DMPS_INVALID_U16);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("C5:%d\n", coefficient[5], "C5:%s\n",\
            SELF_CHECK_STR_NO_USE, coefficient[5], SYS_DMPS_INVALID_U16);
    }

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "             RxCtle(en/value)                                         \n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");
    for(idx = 0; idx < self_check_info->serdes_num; idx++)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "             ");
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("%u/", SELF_CHECK_VALUE_NO_USE, "%s/",\
            self_check_info->serdes_info[idx].rx_ctle_en ? "Enable" : "Disable", self_check_info->serdes_info[idx].rx_ctle_en, invalid_2bit);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("Value0:%u ", self_check_info->serdes_info[idx].rx_ctle.value[0], "Value0:%s ",\
            SELF_CHECK_STR_NO_USE, self_check_info->serdes_info[idx].rx_ctle.value[0], SYS_DMPS_INVALID_U16);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("Value1:%u ", self_check_info->serdes_info[idx].rx_ctle.value[1], "Value1:%s ",\
            SELF_CHECK_STR_NO_USE, self_check_info->serdes_info[idx].rx_ctle.value[1], SYS_DMPS_INVALID_U16);
        SELF_CHECK_SERDES_ITEM_PRINT_FORMAT("Value2:%u\n", self_check_info->serdes_info[idx].rx_ctle.value[2], "Value2:%s\n",\
            SELF_CHECK_STR_NO_USE, self_check_info->serdes_info[idx].rx_ctle.value[2], SYS_DMPS_INVALID_U16);
    }

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------\n");

    return CTC_E_NONE;
}

int32
sys_usw_mac_self_checking(uint8 lchip, uint32 gport)
{
    uint16 lport = 0;

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);

    if(DRV_IS_DUET2(lchip) || DRV_IS_TSINGMA(lchip) || DRV_IS_TMM(lchip) || DRV_IS_AT(lchip))
    {   /* TM / TM.MX / AT */
        if(MCHIP_DMPS(lchip)->mac_self_checking)
        {
            CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->mac_self_checking(lchip, lport));
            return CTC_E_NONE;
        }
        else
        {
            return CTC_E_NOT_SUPPORT;
        }
    }
    else
    {   /* TM.GX */
        int32 ret = CTC_E_NONE;
        sys_dmps_mac_self_check_info_t* self_check_info = NULL;
        self_check_info = (sys_dmps_mac_self_check_info_t*)mem_malloc(MEM_DMPS_MODULE, sizeof(sys_dmps_mac_self_check_info_t));
        if(NULL == self_check_info)
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% NO MEMORY. | %s()@%d\n", __FUNCTION__, __LINE__);
            return CTC_E_NO_MEMORY;
        }

        sal_memset(self_check_info, SYS_DMPS_INVALID_U8, sizeof(sys_dmps_mac_self_check_info_t));

        if(MCHIP_DMPS(lchip)->mac_get_self_check_info)
        {
            CTC_ERROR_GOTO(MCHIP_DMPS(lchip)->mac_get_self_check_info(lchip, lport, (void*)self_check_info),\
                ret, RELEASE_PTR_RETURN);
        }
        else
        {
            ret = CTC_E_INVALID_PTR;
            goto RELEASE_PTR_RETURN;
        }

        CTC_ERROR_GOTO(sys_usw_mac_self_check_print((void*)self_check_info), ret, RELEASE_PTR_RETURN);

RELEASE_PTR_RETURN:
        mem_free(self_check_info);

        return ret;
    }
}

int32
sys_usw_dmps_serdes_set_property(uint8 lchip, ctc_chip_property_t chip_prop, void* p_value)
{
    int32 ret = 0;
    uint16 serdes_id = 0;
    uint16 lport = 0;
    uint32 serdes_speed = 0;
    uint32 an_en = 0;
    ctc_chip_serdes_loopback_t* p_loopback = (ctc_chip_serdes_loopback_t*)p_value;

    if(DRV_IS_TMG(lchip))
    {
        ret = sys_usw_dmps_serdes_api_set_property(lchip, chip_prop, p_value);
    }
    else
    {
        if(MCHIP_DMPS(lchip)->serdes_set_property)
        {
            /* 1. check parameter validity */
            if (DRV_IS_AT(lchip))
            {
                /*1.1 if serdes speed is none, cannot set serdes prop (only support line swap)*/
                serdes_id = *((uint16*)p_value);
                CTC_ERROR_RETURN(sys_usw_dmps_db_get_serdes_speed(lchip, serdes_id, &serdes_speed));
                if ((0 == serdes_speed) && (CTC_CHIP_PROP_SERDES_MAP != chip_prop))
                {
                    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Serdes speed is zero, cannot set property\n");
                    return CTC_E_NOT_SUPPORT;
                }

                /*1.2 before set loopback mode, check if auto-neg is enabled*/
                if ((CTC_CHIP_PROP_SERDES_LOOPBACK == chip_prop) && (p_loopback->enable))
                {
                    CTC_ERROR_RETURN(sys_usw_dmps_db_get_lport_by_psd(lchip, serdes_id, &lport));
                    CTC_ERROR_RETURN(sys_usw_dmps_get_mac_property(lchip, lport, CTC_PORT_PROP_AUTO_NEG_EN, &an_en));
                    if (an_en)
                    {
                        SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Port enable auto-neg, serdes cannot set loopback\n");
                        return CTC_E_NOT_SUPPORT;
                    }
                }
            }
            ret = MCHIP_DMPS(lchip)->serdes_set_property(lchip, chip_prop, p_value);
        }
    }

    return ret;
}

int32
sys_usw_dmps_serdes_download_firmware(uint8 lchip, uint16 serdes_id, uint8 flag)
{
    int32 ret = 0;

    if(DRV_IS_AT(lchip))
    {
        if(MCHIP_DMPS(lchip)->serdes_download_firmware)
        {
            ret = MCHIP_DMPS(lchip)->serdes_download_firmware(lchip, serdes_id, flag);
        }
    }
    else
    {
        return CTC_E_INVALID_PTR;
    }

    return ret;
}

int32
sys_usw_dmps_serdes_get_property(uint8 lchip, ctc_chip_property_t chip_prop, void* p_value)
{
    int32 ret = 0;

    if(DRV_IS_TMG(lchip))
    {
        ret = sys_usw_dmps_serdes_api_get_property(lchip, chip_prop, p_value);
    }
    else
    {
        if(MCHIP_DMPS(lchip)->serdes_get_property)
        {
            ret = MCHIP_DMPS(lchip)->serdes_get_property(lchip, chip_prop, p_value);
        }
        else return CTC_E_INVALID_PTR;
    }

    return ret;
}

/* dynamic switch */
int32
sys_usw_dmps_serdes_set_mode(uint8 lchip, ctc_chip_serdes_info_t* p_serdes_info)
{
    uint16 drv_port = 0;
    uint16 lport    = 0;
    uint32 chan_id  = 0;
    uint8  lsd      = 0;
    sys_dmps_port_info_t port_info = {0};
    sys_datapath_serdes_info_t* p_serdes = NULL;

    SYS_DMPS_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_serdes_info);

    if (p_serdes_info->serdes_id >= MCHIP_CAP(SYS_CAP_DMPS_SERDES_NUM_PER_SLICE))
    {
        return CTC_E_INVALID_PARAM;
    }

    if (p_serdes_info->serdes_mode >= CTC_CHIP_MAX_SERDES_MODE)
    {
        return CTC_E_INVALID_PARAM;
    }

    if(MCHIP_DMPS(lchip)->serdes_set_mode)
    {
        p_serdes_info->serdes_id = sys_usw_datapath_serdes_map(lchip, p_serdes_info->serdes_id);
        CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->serdes_set_mode(lchip, p_serdes_info));
        p_serdes_info->serdes_id = sys_usw_datapath_serdes_map(lchip, p_serdes_info->serdes_id);
    }
    else
    {
        return CTC_E_INVALID_PTR;
    }

    if (CTC_CHIP_SERDES_NONE_MODE != p_serdes_info->serdes_mode)
    {
        if(SYS_USW_DMPS_IS_OLD_DB(lchip))
        {
            CTC_ERROR_RETURN(_sys_usw_datapath_get_logical_serdes_id_by_physical(lchip, (uint8)p_serdes_info->serdes_id, &lsd));
            CTC_ERROR_RETURN(sys_usw_datapath_get_serdes_info(lchip, lsd, &p_serdes));

            drv_port = p_serdes->lport;
            lport = SYS_MAP_DRV_LPORT_TO_SYS_LPORT(drv_port);
        }
        else
        {
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_lport_by_psd(lchip, p_serdes_info->serdes_id, &lport));
        }
        port_info.dir_bmp = CHAN_DIR_TX;
        port_info.index = 0;
        port_info.lport = lport;
        CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_property(lchip, &port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
        CTC_ERROR_RETURN(sys_usw_peri_set_dlb_chan_type(lchip, chan_id));
    }

    return CTC_E_NONE;
}

int32
sys_usw_dmps_get_sfd_en(uint8 lchip, uint16 lport, uint32 *enable)
{
    CTC_PTR_VALID_CHECK(enable);

    MCHIP_DMPS_CB(mac_get_sfd_en, lchip, lport, enable);

    return CTC_E_NONE;
}

int32
sys_usw_dmps_set_rx_pmac_sfd_en(uint8 lchip, uint16 lport, uint32 enable)
{
    MCHIP_DMPS_CB(mac_set_rx_pmac_sfd_en, lchip, lport, enable);

    return CTC_E_NONE;
}

int32
sys_usw_dmps_set_tx_pmac_sfd_en(uint8 lchip, uint16 lport, uint32 enable)
{
    MCHIP_DMPS_CB(mac_set_tx_pmac_sfd_en, lchip, lport, enable);

    return CTC_E_NONE;
}

int32
sys_usw_dmps_set_sfd_en(uint8 lchip, uint16 lport, uint32 enable)
{
    MCHIP_DMPS_CB(mac_set_sfd_en, lchip, lport, enable);

    return CTC_E_NONE;
}

int32
sys_usw_dmps_set_port_property(uint8 lchip, uint32 gport, uint8 dmps_port_prop, void *p_value)
{
    int32  ret = CTC_E_NONE;
    uint16 lport = 0;

    CTC_PTR_VALID_CHECK(p_value);

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);

    switch (dmps_port_prop)
    {
    case SYS_PORT_API_DMPS_PROP_XPIPE_RX:
        ret = sys_usw_dmps_set_mac_property(lchip, lport, CTC_PORT_PROP_XPIPE_EN, *(uint32*)p_value);
        break;
    case SYS_PORT_API_DMPS_PROP_XPIPE_TX:
        ret = sys_usw_dmps_set_mac_property(lchip, lport, CTC_PORT_PROP_XPIPE_MODE, *(uint32*)p_value);
        break;
    case SYS_PORT_API_DMPS_PROP_RX_PMAC_SFD_ENABLE:
        ret = sys_usw_dmps_set_rx_pmac_sfd_en(lchip, lport, *(uint32*)p_value);
        break;
    case SYS_PORT_API_DMPS_PROP_TX_PMAC_SFD_ENABLE:
        ret = sys_usw_dmps_set_tx_pmac_sfd_en(lchip, lport, *(uint32*)p_value);
        break;
    case SYS_PORT_API_DMPS_PROP_SFD_ENABLE:
        ret = sys_usw_dmps_set_sfd_en(lchip, lport, *(uint32*)p_value);
        break;
    case SYS_PORT_API_DMPS_PROP_TX_PRIVATE_INT_EN:
        ret = sys_usw_mac_set_tx_private_int_en(lchip, lport, *(uint32*)p_value);
        break;
    case SYS_PORT_API_DMPS_PROP_TX_CHKSUM_UPD_EN:
        ret = sys_usw_mac_set_tx_chksum_upd_en(lchip, lport, *(uint32*)p_value);
        break;
    /*
    case SYS_PORT_API_DMPS_PROP_SET_PRIORITY:
        ret = sys_usw_dmps_set_mac_property(lchip, lport, CTC_PORT_PROP_XFABRIC_TYPE, *(uint32*)p_value);
        break;
    */
    default:
        return CTC_E_INVALID_PARAM;
    }

    return ret;
}

int32
sys_usw_dmps_get_port_property(uint8 lchip, sys_dmps_port_info_t* port_info, uint8 dmps_port_prop, void *p_value)
{
    int32  ret = CTC_E_NONE;
    uint8  i   = 0;
    uint16 chip_port = 0;
    uint16 serdes_id = 0;
    uint8 serdes_num = 0;
    sys_datapath_lport_attr_t* p_port = NULL;
    sys_dmps_serdes_info_t *p_dmps_serdes = NULL;
    sys_dmps_flexe_phy_inst_t *p_dmps_flexe_phy_inst = NULL;
    sys_dmps_flexe_phy_oh_sync_t *p_dmps_flexe_phy_oh_sync = NULL;    
    uint32 *p_tmp_value = NULL;
    uint16 tmp_lport = 0;    /* temp lport */
    uint16 ext_lport = 0;    /* first extender lport */
    uint16 lport     = 0;

    CTC_PTR_VALID_CHECK(p_value);
    CTC_PTR_VALID_CHECK(port_info);

    lport = port_info->lport;

    switch (dmps_port_prop)
    {
    case SYS_PORT_API_DMPS_PROP_MAC_ID:
        p_tmp_value = (uint32 *)p_value;
        CTC_ERROR_RETURN(sys_usw_mac_get_lport_by_extlport(lchip, lport, &lport));
        ret = sys_usw_mac_get_port_capability(lchip, lport, &p_port);
        if(ret < 0)
        {
            *p_tmp_value = DMPS_INVALID_VALUE_U32;
            return ret;
        }

        if ((p_port->port_type != SYS_DMPS_NETWORK_PORT) && (!SYS_TMM_IS_CPUMAC_PORT(p_port->port_type)))
        {
            *p_tmp_value = DMPS_INVALID_VALUE_U32;
        }
        else
        {
            *p_tmp_value = p_port->mac_id;
        }
        break;
    case SYS_PORT_API_DMPS_PROP_CHAN_ID:
        p_tmp_value = (uint32 *)p_value;
        CTC_ERROR_RETURN(sys_usw_mac_get_lport_by_extlport(lchip, lport, &lport));
        ret = sys_usw_mac_get_port_capability(lchip, lport, &p_port);
        if (ret < 0)
        {
            *p_tmp_value = SYS_DMPS_INVALID_CHAN_ID;
            return ret;
        }
        *p_tmp_value = p_port->chan_id;
        break;
    case SYS_PORT_API_DMPS_PROP_SLICE_ID:
        p_tmp_value = (uint32 *)p_value;
        *p_tmp_value = 0;
        break;
    case SYS_PORT_API_DMPS_PROP_SERDES:
#ifdef EMULATION_ENV /*EMULATION testing*/
            break;
#endif
            p_dmps_serdes = (sys_dmps_serdes_info_t*)p_value;
            CTC_ERROR_RETURN(sys_usw_mac_get_lport_by_extlport(lchip, lport, &lport));
            ret = sys_usw_mac_get_port_capability(lchip, lport, &p_port);
            if (ret < 0 || !(SYS_DMPS_NETWORK_PORT == p_port->port_type || SYS_DMPS_INACTIVE_NETWORK_PORT == p_port->port_type))
            {
                p_dmps_serdes->serdes_id[0] = 0xff;
                p_dmps_serdes->serdes_id[1] = 0xff;
                p_dmps_serdes->serdes_id[2] = 0xff;
                p_dmps_serdes->serdes_id[3] = 0xff;
                p_dmps_serdes->serdes_mode = 0xff;
                p_dmps_serdes->serdes_num = 0;
                return ret;
            }
            else
            {
                if(DRV_IS_TMM(lchip)) /*TMM*/
                {
                    if (p_port->serdes_num <= SYS_MAX_SERDES_NUM_PER_PORT)
                    {
                        for (i = 0; i < p_port->serdes_num; i++)
                        {
                            p_dmps_serdes->serdes_id[i] = p_port->multi_serdes_id[i];
                        }
                        p_dmps_serdes->serdes_mode = p_port->pcs_mode;
                        p_dmps_serdes->serdes_num  = p_port->serdes_num;
                    }
                }
                else /*D2 TM*/
                {
                    chip_port = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(lport);
                    CTC_ERROR_RETURN(sys_usw_datapath_get_serdes_with_lport(lchip, chip_port, &serdes_id, &serdes_num));

                    p_dmps_serdes->serdes_id[0] = 0xff;
                    p_dmps_serdes->serdes_id[1] = 0xff;
                    p_dmps_serdes->serdes_id[2] = 0xff;
                    p_dmps_serdes->serdes_id[3] = 0xff;
                    if ((CTC_CHIP_SERDES_CG_MODE == p_port->pcs_mode) || (CTC_CHIP_SERDES_XLG_MODE == p_port->pcs_mode)
                        || (CTC_CHIP_SERDES_XAUI_MODE == p_port->pcs_mode) || (CTC_CHIP_SERDES_DXAUI_MODE == p_port->pcs_mode)
                        || ((CTC_CHIP_SERDES_LG_MODE == p_port->pcs_mode)&& (0 == p_port->flag)))
                    {
                        for (i = 0; i < serdes_num; i++)
                        {
                            p_dmps_serdes->serdes_id[i] = serdes_id + i;
                        }
                    }
                    else if ((CTC_CHIP_SERDES_LG_MODE == p_port->pcs_mode)&& (1 == p_port->flag))
                    {
                        if (chip_port % 4)  /* 50G port 2 */
                        {
                            p_dmps_serdes->serdes_id[0] = serdes_id;
                            p_dmps_serdes->serdes_id[1] = serdes_id+3;
                        }
                        else    /* 50G port 0 */
                        {
                            p_dmps_serdes->serdes_id[0] = serdes_id;
                            p_dmps_serdes->serdes_id[1] = serdes_id+1;
                        }
                    }
                    else
                    {
                        p_dmps_serdes->serdes_id[0] = serdes_id;
                    }
                    p_dmps_serdes->serdes_mode = p_port->pcs_mode;
                    p_dmps_serdes->serdes_num = serdes_num;
                }
            }
        break;
    case SYS_PORT_API_DMPS_PROP_SERDES_LOGIC:        
            p_dmps_serdes = (sys_dmps_serdes_info_t*)p_value;
            CTC_ERROR_RETURN(sys_usw_mac_get_lport_by_extlport(lchip, lport, &lport));
            ret = sys_usw_mac_get_port_capability(lchip, lport, &p_port);
            if (ret < 0 || !(SYS_DMPS_NETWORK_PORT == p_port->port_type || SYS_DMPS_INACTIVE_NETWORK_PORT == p_port->port_type))
            {
                p_dmps_serdes->serdes_id[0] = 0xff;
                p_dmps_serdes->serdes_id[1] = 0xff;
                p_dmps_serdes->serdes_id[2] = 0xff;
                p_dmps_serdes->serdes_id[3] = 0xff;
                p_dmps_serdes->serdes_mode = 0xff;
                p_dmps_serdes->serdes_num = 0;
                return ret;
            }
            else
            {
                chip_port = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(lport);
                CTC_ERROR_RETURN(sys_usw_datapath_get_serdes_with_lport(lchip, chip_port, &serdes_id, &serdes_num));
                for (i = 0; i < serdes_num; i++)
                {
                    p_dmps_serdes->serdes_id[i] = serdes_id + i;
                }
                p_dmps_serdes->serdes_mode = p_port->pcs_mode;
                p_dmps_serdes->serdes_num = serdes_num;
            }
        break;
    case SYS_PORT_API_DMPS_PROP_PORT_TYPE:
        p_tmp_value = (uint32 *)p_value;
        CTC_ERROR_RETURN(sys_usw_mac_get_lport_by_extlport(lchip, lport, &lport));
        ret = sys_usw_mac_get_port_capability(lchip, lport, &p_port);
        if (ret < 0)
        {
            *p_tmp_value = 0xff;
            return ret;
        }
        *p_tmp_value = p_port->port_type;
        break;
    case SYS_PORT_API_DMPS_PROP_SPEED_MODE:
        p_tmp_value = (uint32 *)p_value;
        ret = sys_usw_mac_get_port_capability(lchip, lport, &p_port);
        if (ret < 0)
        {
            *p_tmp_value = 0xff;
            return ret;
        }
        *p_tmp_value = p_port->speed_mode;
        break;
    case SYS_PORT_API_DMPS_PROP_WLAN_ENABLE:
        p_tmp_value = (uint32 *)p_value;
        *p_tmp_value = sys_usw_datapath_get_wlan_en(lchip);
        break;
    case SYS_PORT_API_DMPS_PROP_DOT1AE_ENABLE:
        p_tmp_value = (uint32 *)p_value;
        *p_tmp_value = sys_usw_datapath_get_dot1ae_en(lchip);
        break;
    case SYS_PORT_API_DMPS_PROP_MAC_STATS_ID:
        p_tmp_value = (uint32 *)p_value;
        tmp_lport = lport;
        /* if port is extender port get local port */
        CTC_ERROR_RETURN(sys_usw_mac_get_lport_by_extlport(lchip, tmp_lport, &lport));
        if (tmp_lport == lport)
        {
            /* if port has been extended, stats need get from extended port */
            sys_usw_mac_get_extlport_by_lport(lchip, tmp_lport, &ext_lport);
            if (tmp_lport != ext_lport)
            {
                *p_tmp_value = 0xff;
                return CTC_E_INVALID_PARAM;
            }
        }
        /* if extender port is not the first extender port return none */
        sys_usw_mac_get_extlport_by_lport(lchip, lport, &ext_lport);
        if (tmp_lport != ext_lport)
        {
            *p_tmp_value = 0xff;
            return CTC_E_INVALID_PARAM;
        }

        ret = sys_usw_mac_get_port_capability(lchip, lport, &p_port);
        if (ret < 0)
        {
            *p_tmp_value = 0xff;
            return ret;
        }

        if ((p_port->port_type != SYS_DMPS_NETWORK_PORT) && (!SYS_TMM_IS_CPUMAC_PORT(p_port->port_type)))
        {
            *p_tmp_value = 0xff;
            break;
        }

        if(DRV_IS_DUET2(lchip))
        {
            *p_tmp_value = p_port->mac_id;
        }
        else if(DRV_IS_TSINGMA(lchip))
        {
            *p_tmp_value = p_port->tbl_id;
        }
        else
        {
            *p_tmp_value = p_port->mac_id;
        }
        break;
    case SYS_PORT_API_DMPS_PROP_TX_PRIVATE_INT_EN:
        ret = sys_usw_mac_get_tx_private_int_en(lchip, lport, (uint32*)p_value);
        break;
    case SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID:
        p_tmp_value = (uint32 *)p_value;
        ret = sys_usw_mac_get_port_capability(lchip, lport, &p_port);
        if (ret < 0)
        {
            *p_tmp_value = SYS_DMPS_INVALID_SUB_CHAN_ID;
            return ret;
        }

        if (SYS_DMPS_RSV_PORT == p_port->port_type)
        {
            *p_tmp_value = SYS_DMPS_INVALID_SUB_CHAN_ID;
        }
        else
        {
            *p_tmp_value = p_port->sub_chan_id; /*AT_TODO*/
        }
        break;
    case SYS_PORT_API_DMPS_PROP_GET_PHY_INST_ID:
        p_dmps_flexe_phy_inst = (sys_dmps_flexe_phy_inst_t*)p_value;
        ret = sys_usw_flexe_get_phy_inst_id(lchip, p_dmps_flexe_phy_inst->dp_id, p_dmps_flexe_phy_inst->asic_inst_id[0], \
            &p_dmps_flexe_phy_inst->serdes_id, &p_dmps_flexe_phy_inst->instance_id);
        break;
    case SYS_PORT_API_DMPS_PROP_GET_OH_SYNC:
        p_dmps_flexe_phy_oh_sync = (sys_dmps_flexe_phy_oh_sync_t*)p_value;
        ret = sys_usw_flexe_get_phy_oh_sync(lchip, p_dmps_flexe_phy_oh_sync->serdes_id, &p_dmps_flexe_phy_oh_sync->enable);
        break;
    case SYS_PORT_API_DMPS_PROP_GET_DP_ASICINST_ID:
        p_dmps_flexe_phy_inst = (sys_dmps_flexe_phy_inst_t*)p_value;
        ret = sys_usw_flexe_get_dp_asic_id(lchip, p_dmps_flexe_phy_inst->serdes_id, p_dmps_flexe_phy_inst->instance_id, \
            &p_dmps_flexe_phy_inst->dp_id, p_dmps_flexe_phy_inst->asic_inst_id);
        break;
    case SYS_PORT_API_DMPS_PROP_MAC_ID_P:
        p_tmp_value = (uint32 *)p_value;
        CTC_ERROR_RETURN(sys_usw_mac_get_lport_by_extlport(lchip, lport, &lport));
        ret = sys_usw_mac_get_port_capability(lchip, lport, &p_port);
        if (ret < 0)
        {
            *p_tmp_value = 0xff;
            return ret;
        }
        if ((p_port->port_type != SYS_DMPS_NETWORK_PORT) && (!SYS_TMM_IS_CPUMAC_PORT(p_port->port_type)))
        {
            *p_tmp_value = 0xff;
        }
        else
        {
            *p_tmp_value = p_port->mac_id_aps;
        }

        break;
    case SYS_PORT_API_DMPS_PROP_PHY_PORT_CHAN_ID:
        p_tmp_value = (uint32 *)p_value;
        ret = sys_usw_mac_get_port_capability(lchip, lport, &p_port);
        if (ret < 0)
        {
            *p_tmp_value = SYS_DMPS_INVALID_CHAN_ID;
            return ret;
        }

        if (SYS_DMPS_RSV_PORT == p_port->port_type)
        {
            *p_tmp_value = SYS_DMPS_INVALID_CHAN_ID;
        }
        else
        {
            *p_tmp_value = p_port->chan_id;
        }
        break;
    case SYS_PORT_API_DMPS_PROP_PHY_PORT_TYPE:
        p_tmp_value = (uint32 *)p_value;
        ret = sys_usw_mac_get_port_capability(lchip, lport, &p_port);
        if (ret < 0)
        {
            *p_tmp_value = SYS_DMPS_INVALID_CHAN_ID;
            return ret;
        }
        *p_tmp_value = p_port->port_type;
        break;
    case SYS_PORT_API_DMPS_PROP_GET_MAC_INDEX:
        p_tmp_value = (uint32 *)p_value;
        CTC_ERROR_RETURN(sys_usw_mac_get_lport_by_extlport(lchip, lport, &lport));
        ret = sys_usw_mac_get_port_capability(lchip, lport, &p_port);
        if (ret < 0)
        {
            *p_tmp_value = 0xff;
            return ret;
        }
        *p_tmp_value = p_port->internal_mac_idx;
        break;
    case SYS_PORT_API_DMPS_PROP_GET_SGMAC_INDEX:
        p_tmp_value = (uint32 *)p_value;
        CTC_ERROR_RETURN(sys_usw_mac_get_lport_by_extlport(lchip, lport, &lport));
        ret = sys_usw_mac_get_port_capability(lchip, lport, &p_port);
        if (ret < 0)
        {
            *p_tmp_value = 0xff;
            return ret;
        }
        *p_tmp_value = p_port->sgmac_idx;
        break;
    case SYS_PORT_API_DMPS_PROP_GET_PMAC_ID:
        p_tmp_value = (uint32 *)p_value;
        CTC_ERROR_RETURN(sys_usw_mac_get_lport_by_extlport(lchip, lport, &lport));
        ret = sys_usw_mac_get_port_capability(lchip, lport, &p_port);
        if (ret < 0)
        {
            *p_tmp_value = 0xff;
            return ret;
        }
        *p_tmp_value = p_port->xpipe_en?p_port->pmac_id:SYS_DMPS_INVALID_U8;
        break;
    case SYS_PORT_API_DMPS_PROP_GET_PMAC_CHAN_ID:
        p_tmp_value = (uint32 *)p_value;
        ret = sys_usw_mac_get_lport_by_extlport(lchip, lport, &lport);
        ret = ret?ret:sys_usw_mac_get_port_capability(lchip, lport, &p_port);
        if (ret < 0)
        {
            *p_tmp_value = SYS_COMMON_USELESS_CHANNEL;
            return ret;
        }
        *p_tmp_value = (DRV_FROM_TM(lchip)&&p_port->xpipe_en)?p_port->pmac_chanid:SYS_DMPS_INVALID_U8;
        break;
    case SYS_PORT_API_DMPS_PROP_PP_ID:
        p_tmp_value = (uint32 *)p_value;
        *p_tmp_value = 0;
        break;
    case SYS_PORT_API_DMPS_PROP_DP_ID:
        p_tmp_value = (uint32 *)p_value;
        *p_tmp_value = 0;
        break;
    default:
        return CTC_E_INVALID_PARAM;
    }

    return ret;
}

/*chan_id is global chan id, return port is sys Port*/
uint16
sys_usw_dmps_get_lport_with_chan(uint8 lchip, uint8 dir_bmp, uint16 chan_id)
{
    uint32 cmd = 0;
    IpeHeaderAdjustPhyPortMap_m port_map;
    uint16 chip_lport = 0;
    uint16 drv_lport = 0;

    cmd = DRV_IOR((IpeHeaderAdjustPhyPortMap_t), DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, chan_id, cmd, &port_map);

    chip_lport = GetIpeHeaderAdjustPhyPortMap(V,localPhyPort_f,&port_map);

    drv_lport = chip_lport;
    sys_usw_mac_get_extlport_by_lport(lchip, drv_lport, &drv_lport);

    return SYS_MAP_DRV_LPORT_TO_SYS_LPORT(drv_lport);
}

uint16
sys_usw_dmps_get_lport_with_subchan(uint8 lchip, uint8 sub_chan_id)
{
    uint32 cmd = 0;
    IpeHeaderAdjustPhyPortMap_m port_map;
    IpeHeaderAdjustChannelPortMap_m chan_map;
    uint16 chip_lport = 0;
    uint16 drv_lport = 0;
    uint8 dp_id = sub_chan_id / MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM);
    uint8 sub_chan = sub_chan_id % MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM);
    uint16 chan_id = 0;

    cmd = DRV_IOR(IpeHeaderAdjustChannelPortMap_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, sub_chan, DRV_CMD_PP_EN(cmd), &chan_map);
    chan_id = dp_id ? GetIpeHeaderAdjustChannelPortMap(V,g_1_ppSrcPort_f,&port_map)
                    : GetIpeHeaderAdjustChannelPortMap(V,g_0_ppSrcPort_f,&port_map);

    cmd = DRV_IOR((IpeHeaderAdjustPhyPortMap_t), DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, chan_id, cmd, &port_map);

    chip_lport = GetIpeHeaderAdjustPhyPortMap(V,localPhyPort_f,&port_map);

    drv_lport = chip_lport;
    sys_usw_mac_get_extlport_by_lport(lchip, drv_lport, &drv_lport);

    return SYS_MAP_DRV_LPORT_TO_SYS_LPORT(drv_lport);
}

uint16
sys_usw_dmps_get_lport_with_subchan_db(uint8 lchip, uint8 dir_bmp, uint8 core, uint8 pp, uint8 dp, uint8 sub_chan_id)
{
    return sys_usw_dmps_get_lport_with_subchan(lchip, sub_chan_id);
}

/*mac_id is global mac id, return port is sys Port*/
uint16
sys_usw_dmps_get_lport_with_mac(uint8 lchip, uint16 mac_id)
{
    uint16 chip_lport = 0;
    uint16 drv_lport = 0;

    if(SYS_USW_DMPS_IS_OLD_DB(lchip))
    {
        chip_lport = sys_usw_datapath_get_lport_with_mac(lchip, mac_id);
    }
    else
    {
        chip_lport = sys_usw_dmps_db_get_lport_with_mac(lchip, mac_id);
    }

    if (SYS_COMMON_USELESS_MAC == chip_lport)
    {
        return SYS_COMMON_USELESS_MAC;
    }

    drv_lport = chip_lport;
    sys_usw_mac_get_extlport_by_lport(lchip, drv_lport, &drv_lport);

    return SYS_MAP_DRV_LPORT_TO_SYS_LPORT(drv_lport);
}

/*mac_id is global mac id, return port is sys Port*/
/*TSINGMA ONLY*/
uint16
sys_usw_dmps_get_lport_with_mac_tbl_id(uint8 lchip, uint16 mac_tbl_id)
{
    uint16 chip_lport = 0;
    uint16 drv_lport = 0;
    uint16 slice_mac = 0;

    slice_mac = mac_tbl_id;

    chip_lport = sys_usw_datapath_get_lport_with_mac_tbl_id(lchip, slice_mac);
    if (SYS_COMMON_USELESS_MAC == chip_lport)
    {
        return SYS_COMMON_USELESS_MAC;
    }

    drv_lport = chip_lport;
    sys_usw_mac_get_extlport_by_lport(lchip, drv_lport, &drv_lport);

    return SYS_MAP_DRV_LPORT_TO_SYS_LPORT(drv_lport);
}

/*pp_port --> channelId*/
int32
sys_dmps_get_sub_chan_by_chan(uint8 lchip, uint8 dir_bmp, uint16 chan, uint16* sub_chan, uint8* pp_id, uint8* dp_id)
{
    uint32 cmd = 0;
    uint32 value = 0;
    UcQWritePortChannelMap_m uc_chan_map;

    if (DRV_IS_AT(lchip))
    {
        lchip = SYS_PP_BASE(lchip);
        cmd = DRV_IOR(UcQWritePortChannelMap_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan, cmd, &uc_chan_map));
        value = GetUcQWritePortChannelMap(V, g_0_channelId_f, &uc_chan_map);
        if (sub_chan)
        {
            *sub_chan = value & 0x1F;
        }
        if (dp_id)
        {
            *dp_id = (value >> 5) & 0x1;
        }
        if (pp_id)
        {
            *pp_id = (value >> 6) & 0x7;
        }
    }
    else
    {
        if (sub_chan)
        {
            *sub_chan = chan;
        }
    }
    return CTC_E_NONE;
}

/*get clock core, core_type:0-plla, 1-pllb*/
uint16
sys_usw_dmps_get_core_clock(uint8 lchip, uint8 core_type)
{
#if (SDB_MEM_MODEL == SDB_MODE)
    return 600;
#endif
    return sys_usw_datapath_get_core_clock(lchip, core_type);
}


int32
sys_usw_dmps_set_dlb_chan_type(uint8 lchip, uint16 chan_id)
{

#ifdef EMULATION_ENV
    return 0;
#endif

    CTC_ERROR_RETURN(sys_usw_peri_set_dlb_chan_type(lchip, chan_id));
    return CTC_E_NONE;
}

int32
sys_usw_dmps_get_extport_start_id(uint8 lchip, uint16* p_lport_start)
{
    int32 ret = 0;
    if(MCHIP_DMPS(lchip)->datapath_get_extport_start_id)
    {
        ret = MCHIP_DMPS(lchip)->datapath_get_extport_start_id(lchip, p_lport_start);
    }
    else return CTC_E_INVALID_PTR;

    return ret;
}

int32
sys_usw_dmps_port_swap(uint8 lchip, uint16 src_lport, uint16 dst_lport)
{
    return sys_usw_datapath_port_swap(lchip, src_lport, dst_lport);
}

int32
sys_usw_dmps_bpe_lport_map(uint8 lchip, uint32 gport, uint16 port_base, uint16 port_num, uint8 enable)
{
    uint16 lport = 0;
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);
    return sys_usw_mac_bpe_lport_map(lchip, lport, port_base, port_num, enable);
}

int32
sys_usw_dmps_get_flexe_aps(uint8 lchip, uint16 lport, uint8* p_enable, uint32* p_mac_aps)
{
    int32 ret = 0;
    sys_datapath_lport_attr_t* p_port = NULL;

    SYS_CONDITION_RETURN((!SYS_USW_DMPS_IS_OLD_DB(lchip)), CTC_E_NONE);

    CTC_ERROR_RETURN(sys_usw_mac_get_lport_by_extlport(lchip, lport, &lport));
    ret = sys_usw_mac_get_port_capability(lchip, lport, &p_port);
    if (ret < 0)
    {
        return ret;
    }
    if (p_port->client_bind_num == 2)
    {
        *p_enable = (p_port->mac_id_aps != CTC_MAX_UINT16_VALUE) ?1:0;
        *p_mac_aps = p_port->mac_id_aps;
    }
    else
    {
        *p_enable = 0;
    }
    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_set_flush_en(uint8 lchip, uint16 lport, uint8 enable)
{
#if (1 == SDK_WORK_PLATFORM) || defined(PCS_ONLY) || defined(EMULATOR_ENV)
#else
    uint8  gchip   = 0;
    uint32 gport   = 0;
    uint32 depth   = 0;
    uint32 depth_1 = 0;
    uint32 depth_2 = 0;
    uint32 cnt     = 0;
    uint32 mac_id  = 0;
    uint32 chan_id = 0;
    uint32  delay_ms = 20;

    sys_qos_shape_profile_t shp_profile = {0}; /*this para will not used in port_drop_en since TMM*/
    sys_dmps_port_info_t port_info = {0};

    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    gport = CTC_MAP_LPORT_TO_GPORT((uint32)gchip, (uint32)lport);

    CTC_ERROR_RETURN(sys_usw_queue_get_profile_from_hw(lchip, gport, &shp_profile));

    if(enable)
    {
        /*enable qdrop*/
        CTC_ERROR_RETURN(sys_usw_queue_set_port_drop_en(lchip, gport, TRUE, &shp_profile));

        /*check flush clear*/
        while(cnt < 50)
        {
            CTC_ERROR_RETURN(sys_usw_queue_get_port_depth(lchip, gport, &depth));
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "%% Flush queue depth(%d), port %d \n", depth, gport);
            /* check depth extra 2 times */
            if(0 == depth)
            {
                sal_task_sleep(1);                                
                CTC_ERROR_RETURN(sys_usw_queue_get_port_depth(lchip, gport, &depth_1));
                sal_task_sleep(1);
                CTC_ERROR_RETURN(sys_usw_queue_get_port_depth(lchip, gport, &depth_2));
                if(0 == depth_1 && 0 == depth_2)
                {
                    break;
                }
            }           
            cnt++;
            sal_task_sleep(delay_ms);
        }

        if(cnt >= 50)
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%% Cannot flush queue depth(%d) to Zero, port %d \n", depth, gport);
            CTC_ERROR_RETURN(sys_usw_queue_set_port_drop_en(lchip, gport, FALSE,  &shp_profile));
            return CTC_E_HW_FAIL;
        }
        port_info.dir_bmp = CHAN_DIR_TX;
        port_info.index = 0;
        port_info.lport = lport;
        /*check datapath credit 0*/
        CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_property(lchip, &port_info, SYS_PORT_API_DMPS_PROP_MAC_ID, &mac_id));
        CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_property(lchip, &port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
        MCHIP_DMPS_CB(check_datapath_credit_clear, lchip, mac_id, chan_id);
    }
    else
    {
        /*disable qdrop*/
        CTC_ERROR_RETURN(sys_usw_queue_set_port_drop_en(lchip, gport, FALSE,  &shp_profile));
    }
#endif
    return CTC_E_NONE;

}

/*since AT*/
int32
_sys_usw_dmps_set_mac_en(uint8 lchip, uint16 lport, uint32 enable, uint8 db_upt_flag)
{
    sys_port_api_dmps_info_t port_info = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_info(lchip, lport, &port_info));
    SYS_CONDITION_RETURN(((db_upt_flag) && (enable == port_info.mac_en)), CTC_E_NONE);
    SYS_CONDITION_RETURN(!SYS_USW_IS_NETWORK_PORT(port_info.port_type), CTC_E_NONE);

    /*1. enable queue flush before mac disable*/
    if(!enable)
    {
        CTC_ERROR_RETURN(_sys_usw_dmps_set_flush_en(lchip, lport, TRUE));
    }

    /*2. set mac en/disable config*/
    MCHIP_DMPS_CB(mac_set_mac_en, lchip, lport, (void*)(&port_info), (uint8)enable, db_upt_flag);

    /*3. disable queue flush after mac enable*/
    if(enable)
    {
        CTC_ERROR_RETURN(_sys_usw_dmps_set_flush_en(lchip, lport, FALSE));
    }

    return CTC_E_NONE;
}

int32
_sys_usw_dmps_get_mac_link_up(uint8 lchip, uint16 lport, uint32* p_is_up, uint32 is_port)
{
    int32 ret = 0;

    if(MCHIP_DMPS(lchip)->mac_get_link_up)
    {
        ret = MCHIP_DMPS(lchip)->mac_get_link_up(lchip, lport, p_is_up, is_port);
    }
    else return CTC_E_INVALID_PTR;

    return ret;
}

/*since AT*/
int32
_sys_usw_dmps_get_mac_en(uint8 lchip, uint16 lport, uint32* p_value)
{
    CTC_PTR_VALID_CHECK(p_value);

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_mac_en(lchip, lport, p_value));
    
    return CTC_E_NONE;
}

int32
_sys_usw_dmps_check_fec_valid(uint8 lchip, sys_port_api_dmps_info_t* p_port_info, uint8 fec_val)
{
    uint8 mode_with_fec = DMPS_MAX_MODE_FEC;

    CTC_PTR_VALID_CHECK(p_port_info);

    if(SYS_USW_IS_CPUMAC_PORT(p_port_info->port_type) && 
       ((SYS_DMPS_FEC_TYPE_RS544 == fec_val) || (SYS_DMPS_FEC_TYPE_RS272 == fec_val) || 
        (SYS_DMPS_FEC_TYPE_RS544INT == fec_val) || (SYS_DMPS_FEC_TYPE_RS272INT == fec_val)))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% Unsupported FEC type %u, CPUMAC\n", fec_val);
        return CTC_E_INVALID_CONFIG;
    }

    CTC_ERROR_RETURN(_sys_usw_mac_get_mode_with_fec(lchip, p_port_info->serdes_info.serdes_mode, fec_val, &mode_with_fec));
    if(DMPS_MAX_MODE_FEC == mode_with_fec)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% Unsupported FEC type %u, mode %u\n", 
            fec_val, p_port_info->serdes_info.serdes_mode);
        return CTC_E_INVALID_CONFIG;
    }

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_set_fec(uint8 lchip, uint16 lport, uint32 value)
{
    uint8 mac_toggle = FALSE;
    uint8 fec_val = SYS_PORT_FEC_2_DMPS_FEC(value);
    uint8 fec_val_cur = SYS_DMPS_FEC_TYPE_MAX;
    sys_port_api_dmps_info_t port_info = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_info(lchip, lport, &port_info));

    /*1. config para check*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_fec_type(lchip, lport, &fec_val_cur));
    SYS_CONDITION_RETURN(fec_val_cur == fec_val, CTC_E_NONE);
    CTC_ERROR_RETURN(_sys_usw_dmps_check_fec_valid(lchip, &port_info, fec_val));

    /*2. reset mac/pcs*/
    if(port_info.mac_en)
    {
        mac_toggle = TRUE;
        CTC_ERROR_RETURN(_sys_usw_dmps_set_mac_en(lchip, lport, FALSE, TRUE));
    }

    /*3. FEC config*/
    MCHIP_DMPS_CB(mac_set_fec, lchip, lport, (void*)(&port_info), fec_val);

    /*4. release mac/pcs*/
    if(mac_toggle)
    {
        CTC_ERROR_RETURN(_sys_usw_dmps_set_mac_en(lchip, lport, TRUE, TRUE));
    }

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_get_fec(uint8 lchip, uint16 lport, uint32* p_value)
{
    uint8 fec_val = SYS_DMPS_FEC_TYPE_MAX;

    CTC_PTR_VALID_CHECK(p_value);
    
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_fec_type(lchip, lport, &fec_val));

    *p_value = SYS_DMPS_FEC_2_PORT_FEC(fec_val);

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_set_an_en(uint8 lchip, uint16 lport, uint32 value, uint8 restart)
{
    uint8  port_type = 0;
    uint8  enable = value ? 1 : 0;
    uint32 val32 = 0;
    uint32 stat = 0;
    ctc_chip_serdes_loopback_t lpbk_param = {0};
    sys_port_api_dmps_info_t port_info = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_info(lchip, lport, &port_info));

    /*duplicate config avoidance*/
    if(0 == sys_usw_chip_get_reset_hw_en(lchip))
    {
        CTC_ERROR_RETURN(_sys_usw_dmps_get_an_en(lchip, lport, &val32));
        SYS_CONDITION_RETURN(((val32 && enable) || ((!val32) && (!enable))), CTC_E_NONE);
    }

    if(SYS_MAC_IS_MODE_SUPPORT_CL73(port_info.serdes_info.serdes_mode))
    {
        /*1.1 para check: check port whether valid */
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_type(lchip, lport, &port_type));
        SYS_CONDITION_RETURN(!SYS_USW_IS_NETWORK_PORT(port_type), CTC_E_INVALID_PORT);

        /*1.2 para check: if unidir enable, cannot set AN enable*/
        MCHIP_DMPS_CB(mac_get_internal_property, lchip, lport, CTC_PORT_PROP_UNIDIR_EN, &stat);
        if(enable && stat)
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% lport %u has enable unidir, cannot enable auto-nego! \n", lport);
            return CTC_E_INVALID_CONFIG;
        }

        /*1.3 para check: if serdes loopback enable, cannot set enable */
        CTC_ERROR_RETURN(_sys_usw_dmps_get_loopback_en(lchip, lport, (void*)&lpbk_param));

        /*when enable internal/local loopback,data from TX are sent back to RX, thsre's no need to do anything further.
          when enable external loopback,SerDes's state is uncertain, it's suggested to do nothing.*/
        if(lpbk_param.enable)
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Serdes %d has enabled loopback mode %d\n",
                lpbk_param.serdes_id, lpbk_param.mode);
            return CTC_E_INVALID_CONFIG;
        }

        /*2. config an en*/
        MCHIP_DMPS_CB(mac_set_cl73_en, lchip, lport, enable, restart);
    }
    else if(SYS_MAC_IS_MODE_SUPPORT_CL37(port_info.serdes_info.serdes_mode))
    {
        /*1.1 para check: if unidir enable, cannot set AN enable*/
        MCHIP_DMPS_CB(mac_get_internal_property, lchip, lport, CTC_PORT_PROP_UNIDIR_EN, &stat);
        if(enable && stat)
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% lport %u has enable unidir, cannot enable auto-nego! \n", lport);
            return CTC_E_INVALID_CONFIG;
        }
        /*1.2 para check: if parallel detect enable, cannot set AN disable*/
        if(SYS_SERDES_MODE_SUPPORT_PAR_DET(port_info.serdes_info.serdes_mode))
        {
            MCHIP_DMPS_CB(mac_get_internal_property, lchip, lport, CTC_PORT_PROP_PAR_DET_EN, &stat);
            if((!enable) && stat)
            {
                SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% lport %u has enable parallel detect, cannot disable auto-nego. \n", lport);
                return CTC_E_INVALID_CONFIG;
            }
        }
        /*2. config an en*/
        MCHIP_DMPS_CB(mac_set_cl37_en, lchip, lport, enable);
    }

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_get_an_en(uint8 lchip, uint16 lport, uint32* p_value)
{
    sys_port_api_dmps_info_t port_info = {0};

    CTC_PTR_VALID_CHECK(p_value);

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_info(lchip, lport, &port_info));

    if(SYS_MAC_IS_MODE_SUPPORT_CL73(port_info.serdes_info.serdes_mode))
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_cl73_en(lchip, lport, p_value));
    }
    else if(SYS_MAC_IS_MODE_SUPPORT_CL37(port_info.serdes_info.serdes_mode))
    {
        MCHIP_DMPS_CB(mac_get_cl37_en, lchip, lport, p_value);
    }

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_set_an_mode(uint8 lchip, uint16 lport, uint32 value)
{
    uint32 mode_value = 0;
    sys_port_api_dmps_info_t port_info = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_info(lchip, lport, &port_info));

    if(SYS_MAC_IS_MODE_SUPPORT_CL73(port_info.serdes_info.serdes_mode))
    {
        if (CTC_PORT_AUTO_NEG_MODE_OVER_CLOCK == value)
        {
            return CTC_E_NOT_SUPPORT;
        }
    }
    else if(SYS_MAC_IS_MODE_SUPPORT_CL37(port_info.serdes_info.serdes_mode))
    {
        if(CTC_PORT_AUTO_NEG_MODE_1000BASE_X == value)
        {
            mode_value = 0;
            CTC_ERROR_RETURN(_sys_usw_dmps_set_speed(lchip, lport, CTC_PORT_SPEED_1G));
        }
        else if(CTC_PORT_AUTO_NEG_MODE_SGMII_SLAVER == value)
        {
            mode_value = 2;
        }
        MCHIP_DMPS_CB(mac_set_cl37_mode, lchip, lport, mode_value);
    }

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_get_an_mode(uint8 lchip, uint16 lport, uint32* p_value)
{
    uint8 an_mode = 0;
    sys_port_api_dmps_info_t port_info = {0};

    CTC_PTR_VALID_CHECK(p_value);

    CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_info(lchip, lport, &port_info));
    if(SYS_MAC_IS_MODE_SUPPORT_CL73(port_info.serdes_info.serdes_mode))
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_an_mode(lchip, lport, &an_mode));
        SYS_USW_VALID_PTR_WRITE(p_value, an_mode);
    }
    else if(SYS_MAC_IS_MODE_SUPPORT_CL37(port_info.serdes_info.serdes_mode))
    {
        MCHIP_DMPS_CB(mac_get_cl37_mode, lchip, lport, p_value);
    }

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_get_cl37_an_remote_status(uint8 lchip, uint16 lport, uint32 auto_neg_mode, uint32* p_speed, uint32* p_link)
{
    sys_port_api_dmps_info_t port_info = {0};

    CTC_PTR_VALID_CHECK(p_speed);
    CTC_PTR_VALID_CHECK(p_link);

    CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_info(lchip, lport, &port_info));
    if(SYS_MAC_IS_MODE_SUPPORT_CL37(port_info.serdes_info.serdes_mode))
    {
        MCHIP_DMPS_CB(mac_get_cl37_an_remote_status, lchip, lport, auto_neg_mode, p_speed, p_link);
    }

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_get_loopback_en(uint8 lchip, uint16 lport, void* p_lpbk)
{
    uint8 serdes_idx = 0;
    sys_usw_dmps_serdes_id_t psd = {{0}};
    ctc_chip_serdes_loopback_t* lpbk_param = (ctc_chip_serdes_loopback_t*)p_lpbk;

    CTC_PTR_VALID_CHECK(p_lpbk);

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_psd_by_lport(lchip, lport, psd.serdes, &(psd.num)));

    for(serdes_idx = 0; serdes_idx < psd.num; serdes_idx ++)
    {
        lpbk_param->serdes_id = psd.serdes[serdes_idx];
        for(lpbk_param->mode = DMPS_SERDES_LPBK_INTERNAL; lpbk_param->mode < DMPS_SERDES_LPBK_NONE; lpbk_param->mode ++)
        {
            if(DRV_IS_AT(lchip))
            {
                MCHIP_DMPS_CB(serdes_get_loopback_en, lchip, (void*)lpbk_param);
            }
            else    /*From TM.GX,using serdes api*/
            {
                CTC_ERROR_RETURN(sys_usw_dmps_serdes_get_lane_loopback(lchip, lpbk_param->serdes_id, (void*)lpbk_param));
            }
            if(lpbk_param->enable)
            {
                break;
            }
        }
        if(lpbk_param->enable)
        {
            break;
        }
    }

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_set_an_fec(uint8 lchip, uint16 lport, uint32 value)
{
    uint16 dport  = sys_usw_dmps_db_get_dport_by_lport(lchip, lport);
    sys_port_api_dmps_info_t port_info = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_info(lchip, lport, &port_info));

    if(SYS_MAC_IS_MODE_SUPPORT_CL73(port_info.serdes_info.serdes_mode))
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_an_fec(lchip, lport, value));
        CTC_ERROR_RETURN(sys_usw_dmps_anlt_sm_send_an_fec_msg(lchip, dport));
    }
    else
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% FEC not supported\n");
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_get_an_fec(uint8 lchip, uint16 lport, uint32* p_value)
{
    sys_port_api_dmps_info_t port_info = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_info(lchip, lport, &port_info));

    if(SYS_MAC_IS_MODE_SUPPORT_CL73(port_info.serdes_info.serdes_mode))
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_an_fec(lchip, lport, p_value));
    }
    else
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% FEC not supported\n");
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_set_speed(uint8 lchip, uint16 lport, uint32 value)
{
    uint8 mac_toggle = FALSE;
    uint32 an_en = 0;
    uint8  gchip       = 0;
    uint32 gport       = 0;
    uint32 phy_init    = 0;
    sys_port_api_dmps_info_t port_info = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_info(lchip, lport, &port_info));

    /*1. config para check*/
    SYS_CONDITION_RETURN(port_info.speed_mode == value, CTC_E_NONE);
    if(SYS_MAC_IS_MODE_SUPPORT_CL37(port_info.serdes_info.serdes_mode))
    {
        if((value != CTC_PORT_SPEED_1G) && (value != CTC_PORT_SPEED_100M) && (value != CTC_PORT_SPEED_10M))
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Invalid speed %u\n", value);
            return CTC_E_INVALID_PARAM;
        }
    }
    else
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Speed not supported\n");
        return CTC_E_INVALID_PARAM;
    }

    /*2. set phy speed*/
    CTC_ERROR_RETURN(_sys_usw_dmps_get_an_en(lchip, lport, &an_en));
    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    gport = CTC_MAP_LPORT_TO_GPORT(gchip, lport);
    if((CTC_E_NONE == sys_usw_phy_get_phy_property(lchip, gport, CTC_PORT_PROP_PHY_INIT, (void*)&phy_init)) && 
       (phy_init) && (0 == an_en))
    {
        CTC_ERROR_RETURN(sys_usw_phy_set_phy_property(lchip, gport, CTC_PORT_PROP_SPEED, (void*)&value));
    }

    /*3. reset mac/pcs*/
    if(port_info.mac_en)
    {
        mac_toggle = TRUE;
        CTC_ERROR_RETURN(_sys_usw_dmps_set_mac_en(lchip, lport, FALSE, TRUE));
    }

    /*4. config speed*/
    MCHIP_DMPS_CB(mac_set_speed, lchip, lport, (uint8)value);

    /*5. release mac/pcs*/
    if(mac_toggle)
    {
        CTC_ERROR_RETURN(_sys_usw_dmps_set_mac_en(lchip, lport, TRUE, TRUE));
    }

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_get_speed(uint8 lchip, uint16 lport, uint32* p_value)
{
    uint8  speed_mode = 0;

    CTC_PTR_VALID_CHECK(p_value);

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_speed_mode(lchip, lport, &speed_mode));

    *p_value = speed_mode;

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_set_xpipe_en(uint8 lchip, uint16 lport, uint32 value, uint8 dir_bmp)
{
    uint32 xpipe_en_cur = 0;
    sys_port_api_dmps_info_t port_info = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_info(lchip, lport, &port_info));

    /*1. config para check*/
    if(SYS_DMPS_NETWORK_PORT != port_info.port_type)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% lport %u is not a network port! \n", lport);
        return CTC_E_INVALID_PORT;
    }

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_xpipe_en(lchip, lport, &xpipe_en_cur));
    if ((xpipe_en_cur & dir_bmp) == (value ? (dir_bmp) : 0))
    {
        return CTC_E_NONE;
    }

    /*2. dmps xpipe en/dis*/
    MCHIP_DMPS_CB(mac_set_xpipe_en, lchip, lport, value, dir_bmp);

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_get_xpipe_en(uint8 lchip, uint16 lport, uint32* p_value, uint8 dir)
{
    uint32 xpipe_en = 0;

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_xpipe_en(lchip, lport, &xpipe_en));
    *p_value = (xpipe_en & dir) ? TRUE : FALSE;

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_get_daemon_en(uint8 lchip, uint32* p_value)
{
    CTC_PTR_VALID_CHECK(p_value);

    *p_value = p_usw_mac_master[lchip]->polling_status;

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_set_daemon_en(uint8 lchip, uint32 value)
{
    p_usw_mac_master[lchip]->polling_status = (value == 0 ? FALSE : TRUE);

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_get_daemon_gap_ms(uint8 lchip, uint32* p_value)
{
    CTC_PTR_VALID_CHECK(p_value);
    *p_value = p_usw_mac_master[lchip]->polling_gap_ms;
    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_set_daemon_gap_ms(uint8 lchip, uint32 value)
{
    p_usw_mac_master[lchip]->polling_gap_ms = value;
    return CTC_E_NONE;
}

/*since AT*/
void
sys_usw_dmps_daemon_thread(uint8 lchip, uint16 lport)
{
    if(MCHIP_DMPS(lchip)->mac_daemon_thread)
    {
        (void)MCHIP_DMPS(lchip)->mac_daemon_thread(lchip, lport);
    }
}

int32
sys_usw_dmps_set_mac_property_dispatch(uint8 lchip, uint16 lport, ctc_port_property_t port_prop,  uint32 value)
{

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "DMPS set port property, lport:%u, property:%d, value:%d\n", \
                     lport, port_prop, value);
    SYS_MAC_INIT_CHECK();

    switch (port_prop)
    {
        case CTC_PORT_PROP_MAC_EN:
            CTC_ERROR_RETURN(_sys_usw_dmps_set_mac_en(lchip, lport, value, TRUE));
            break;
        case CTC_PORT_PROP_FEC_EN:
            CTC_ERROR_RETURN(_sys_usw_dmps_set_fec(lchip, lport, value));
            break;
        case CTC_PORT_PROP_AUTO_NEG_EN:
            CTC_ERROR_RETURN(_sys_usw_dmps_set_an_en(lchip, lport, value, FALSE));
            break;
        case CTC_PORT_PROP_AUTO_NEG_MODE:
            CTC_ERROR_RETURN(_sys_usw_dmps_set_an_mode(lchip, lport, value));
            break;
        case CTC_PORT_PROP_AUTO_NEG_FEC:
            CTC_ERROR_RETURN(_sys_usw_dmps_set_an_fec(lchip, lport, value));
            break;
        case CTC_PORT_PROP_SPEED:
            CTC_ERROR_RETURN(_sys_usw_dmps_set_speed(lchip, lport, value));
            break;
        case CTC_PORT_PROP_XPIPE_EN:
            CTC_ERROR_RETURN(_sys_usw_dmps_set_xpipe_en(lchip, lport, value, CHAN_DIR_RX));
            break;
        case CTC_PORT_PROP_XPIPE_MODE:
            CTC_ERROR_RETURN(_sys_usw_dmps_set_xpipe_en(lchip, lport, value, CHAN_DIR_TX));
            break;
        default:
            MCHIP_DMPS_CB(mac_set_internal_property, lchip, lport, port_prop, value);
            break;
    }

    if(DRV_IS_DUET2(lchip) || DRV_IS_TSINGMA(lchip) || DRV_IS_TMM(lchip))
    {
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_DATAPATH, SYS_WB_APPID_DATAPATH_SUBID_MASTER, 1);
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_PORT,     SYS_WB_APPID_PORT_SUBID_MAC_PROP,   1);
    }

    return CTC_E_NONE;
}

int32
sys_usw_dmps_get_mac_property_dispatch(uint8 lchip, uint16 lport, ctc_port_property_t port_prop, uint32* p_value)
{

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "DMPS get port property, lport:%u, property:%d\n", \
                     lport, port_prop);
    SYS_MAC_INIT_CHECK();

    switch (port_prop)
    {
        case CTC_PORT_PROP_MAC_EN:
            CTC_ERROR_RETURN(_sys_usw_dmps_get_mac_en(lchip, lport, p_value));
            break;
        case CTC_PORT_PROP_LINK_UP:
            CTC_ERROR_RETURN(_sys_usw_dmps_get_mac_link_up(lchip, lport, p_value, TRUE));
            break;
        case CTC_PORT_PROP_FEC_EN:
            CTC_ERROR_RETURN(_sys_usw_dmps_get_fec(lchip, lport, p_value));
            break;
        case CTC_PORT_PROP_AUTO_NEG_EN:
            CTC_ERROR_RETURN(_sys_usw_dmps_get_an_en(lchip, lport, p_value));
            break;
        case CTC_PORT_PROP_AUTO_NEG_MODE:
            CTC_ERROR_RETURN(_sys_usw_dmps_get_an_mode(lchip, lport, p_value));
            break;
        case CTC_PORT_PROP_AUTO_NEG_FEC:
            CTC_ERROR_RETURN(_sys_usw_dmps_get_an_fec(lchip, lport, p_value));
            break;
        case CTC_PORT_PROP_SPEED:
            CTC_ERROR_RETURN(_sys_usw_dmps_get_speed(lchip, lport, p_value));
            break;
        case CTC_PORT_PROP_XPIPE_EN:
            CTC_ERROR_RETURN(_sys_usw_dmps_get_xpipe_en(lchip, lport, p_value, CHAN_DIR_RX));
            break;
        case CTC_PORT_PROP_XPIPE_MODE:
            CTC_ERROR_RETURN(_sys_usw_dmps_get_xpipe_en(lchip, lport, p_value, CHAN_DIR_TX));
            break;
        default:
            MCHIP_DMPS_CB(mac_get_internal_property, lchip, lport, port_prop, p_value);
            break;
    }

    return CTC_E_NONE;
}

int32
sys_usw_dmps_set_mac_property(uint8 lchip, uint16 lport, ctc_port_property_t port_prop,  uint32 value)
{
    if(SYS_USW_DMPS_IS_OLD_DB(lchip))
    {
        return sys_usw_mac_set_property(lchip, lport, port_prop, value);
    }
    else
    {
        return sys_usw_dmps_set_mac_property_dispatch(lchip, lport, port_prop, value);
    }
}

int32
sys_usw_dmps_get_mac_property(uint8 lchip, uint16 lport, ctc_port_property_t port_prop, uint32* p_value)
{
    if(SYS_USW_DMPS_IS_OLD_DB(lchip))
    {
        return sys_usw_mac_get_property(lchip, lport, port_prop, p_value);
    }
    else
    {
        return sys_usw_dmps_get_mac_property_dispatch(lchip, lport, port_prop, p_value);
    }
}

int32
sys_usw_dmps_set_direction_property(uint8 lchip, uint32 gport, ctc_port_direction_property_t port_prop, ctc_direction_t dir, uint32 value)
{
    int32 ret = 0;
    uint16 lport = 0;

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);
    if(MCHIP_DMPS(lchip)->mac_set_direction_property)
    {
        ret = MCHIP_DMPS(lchip)->mac_set_direction_property(lchip, lport, port_prop, dir, value);
    }
    else return CTC_E_INVALID_PTR;

    return ret;
}

int32
sys_usw_dmps_get_direction_property(uint8 lchip, uint32 gport, ctc_port_direction_property_t port_prop, ctc_direction_t dir, uint32* p_value)
{
    int32 ret = 0;
    uint16 lport = 0;

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);
    if(MCHIP_DMPS(lchip)->mac_get_direction_property)
    {
        ret = MCHIP_DMPS(lchip)->mac_get_direction_property(lchip, lport, port_prop, dir, p_value);
    }
    else return CTC_E_INVALID_PTR;

    return ret;
}

int32
sys_usw_dmps_port_get_link_info(uint8 lchip, uint16 lport, void* p_value)
{
    int32 ret = 0;

    if(MCHIP_DMPS(lchip)->mac_get_link_info)
    {
        ret = MCHIP_DMPS(lchip)->mac_get_link_info(lchip, lport, p_value);
    }
    else return CTC_E_INVALID_PTR;

    return ret;
}

int32
sys_usw_dmps_port_check_datapath_credit_clear(uint8 lchip, uint32 mac_id, uint32 chan_id)
{
    int32 ret = 0;
    if(MCHIP_DMPS(lchip)->check_datapath_credit_clear)
    {
        ret = MCHIP_DMPS(lchip)->check_datapath_credit_clear(lchip, mac_id, chan_id);
    }
    else return CTC_E_INVALID_PTR;

    return ret;
}

int32
sys_usw_dmps_get_internal_chan_start(uint8 lchip, uint8 dp_id, uint16* p_chan_id)
{
    if(MCHIP_DMPS(lchip)->get_internal_chan_start)
    {
        return MCHIP_DMPS(lchip)->get_internal_chan_start(lchip, dp_id, p_chan_id);
    }
    return CTC_E_INVALID_PTR;
}

int32
sys_usw_dmps_port_set_other_misc_chan(uint8 lchip, uint16 lport, uint8 port_type, uint8 speed_mode, uint8 dir_bmp)
{
    int32 ret = 0;
    if(MCHIP_DMPS(lchip)->set_other_misc_chan)
    {
        ret = MCHIP_DMPS(lchip)->set_other_misc_chan(lchip, lport, port_type, speed_mode, dir_bmp);
    }
    else return CTC_E_INVALID_PTR;

    return ret;
}

int32
sys_usw_dmps_port_set_link_info(uint8 lchip, uint16 lport, void* p_value)
{
    int32 ret = 0;

    if(MCHIP_DMPS(lchip)->mac_set_link_info)
    {
        ret = MCHIP_DMPS(lchip)->mac_set_link_info(lchip, lport, p_value);
    }
    else return CTC_E_INVALID_PTR;

    return ret;
}

int32
sys_usw_dmps_port_set_err_inject(uint8 lchip, uint16 lport, void* p_value)
{
    int32 ret = 0;

    if(MCHIP_DMPS(lchip)->mac_set_err_inject)
    {
        ret = MCHIP_DMPS(lchip)->mac_set_err_inject(lchip, lport, p_value);
    }
    else return CTC_E_INVALID_PTR;

    return ret;
}

int32
sys_usw_dmps_port_get_err_inject(uint8 lchip, uint16 lport, void* p_value)
{
    int32 ret = 0;

    if(MCHIP_DMPS(lchip)->mac_get_err_inject)
    {
        ret = MCHIP_DMPS(lchip)->mac_get_err_inject(lchip, lport, p_value);
    }
    else return CTC_E_INVALID_PTR;
    
    return ret;
}

int32
sys_usw_dmps_port_set_cl73_ability_ext(uint8 lchip, uint16 lport, void* p_value)
{
    int32 ret = 0;

    if(MCHIP_DMPS(lchip)->set_cl73_ability_ext)
    {
        ret = MCHIP_DMPS(lchip)->set_cl73_ability_ext(lchip, lport, *(uint32*)p_value);
    }
    else return CTC_E_INVALID_PTR;

    return ret;
}

/*since AT*/
int32
_sys_usw_dmps_mac_isr_dispatch(uint8 lchip, uint32 intr, void* p_data, uint8* p_link_intr, ctc_port_link_status_t* port_link_status)
{
    MCHIP_DMPS_CB(mac_isr_event_dispatch, lchip, intr, p_data, p_link_intr, port_link_status);
    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_cpumac_isr_dispatch(uint8 lchip, uint32 intr, void* p_data, uint8* p_link_intr, ctc_port_link_status_t* port_link_status)
{
    MCHIP_DMPS_CB(cpumac_isr_event_dispatch, lchip, intr, p_data, p_link_intr, port_link_status);
    return CTC_E_NONE;
}

int32
_sys_usw_dmps_dynamic_switch_serdes_get_list(uint8 lchip, ctc_chip_serdes_info_t* p_serdes_info, 
                                                            sys_dmps_ds_list_t* p_list)
{
    MCHIP_DMPS_CB(mac_dynamic_switch_serdes_get_list, lchip, (void*)p_serdes_info, (void*)p_list);
    return CTC_E_NONE;
}

int32
_sys_usw_dmps_dynamic_switch_get_list(uint8 lchip, uint16 lport, ctc_port_if_mode_t* if_mode, 
                                                  sys_dmps_ds_list_t* p_list)
{
    MCHIP_DMPS_CB(mac_dynamic_switch_get_list, lchip, lport, (void*)if_mode, (void*)p_list);
    return CTC_E_NONE;
}

int32
_sys_usw_dmps_dynamic_switch_set_group_power(uint8 lchip, sys_dmps_ds_list_t* p_list, uint8 dyn_flag)
{
    MCHIP_DMPS_CB(mac_dynamic_switch_set_group_power, lchip, (void*)p_list, dyn_flag);
    return CTC_E_NONE;
}

int32
_sys_usw_dmps_dynamic_switch_set_property_clear(uint8 lchip, sys_dmps_ds_list_t* p_list, uint32 option_bmp)
{
    uint8  cnt       = 0;
    uint8  if_mode   = 0;
    uint8  idx       = 0;
    uint8  lpbk_type = 0;
    uint16 dport     = 0;
    uint16 lport     = 0;
    uint32 cl73_en   = 0;
    ctc_chip_serdes_loopback_t lpbk      = {0};
    sys_port_api_dmps_info_t   port_info = {0};
    
    for(cnt = 0; cnt < p_list->src_dport_num; cnt++)
    {
        dport = p_list->src_dport_list[cnt];
        SYS_CONDITION_CONTINUE(FALSE == sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_PORT, dport));
        lport = sys_usw_dmps_db_get_lport_by_dport(lchip, dport);
        SYS_CONDITION_CONTINUE(DMPS_INVALID_VALUE_U16 == lport);

        CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_info(lchip, lport, &port_info));

        /* clear mac enable cfg */
        if (CTC_IS_BIT_SET(option_bmp, DMPS_DS_OPTION_CLEAR_MAC))
        {
            CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property_dispatch(lchip, lport, CTC_PORT_PROP_MAC_EN, FALSE));
        }

        CTC_ERROR_RETURN(sys_usw_dmps_db_get_ifmode(lchip, lport, &if_mode));

        /* clear fec config */
        if (SYS_DMPS_IS_PAM4_MODE(if_mode))
        {
            CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property_dispatch(lchip, lport, CTC_PORT_PROP_FEC_EN, CTC_PORT_FEC_TYPE_RS544));
        }
        else
        {
            CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property_dispatch(lchip, lport, CTC_PORT_PROP_FEC_EN, CTC_PORT_FEC_TYPE_NONE));
        }
        
        ///TODO: tbd
        if(SYS_DMPS_NETWORK_PORT == port_info.port_type)
        {
            uint8 gchip = 0;
            CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
            /* set mac rx pkt disable */
            CTC_ERROR_RETURN(sys_usw_dmps_set_direction_property(lchip, CTC_MAP_LPORT_TO_GPORT(gchip, lport), CTC_PORT_DIR_PROP_MAC_EN, CTC_INGRESS, 0));
            /* disable xpipe */
            CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property_dispatch(lchip, lport, CTC_PORT_PROP_XPIPE_EN, FALSE));
            CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property_dispatch(lchip, lport, CTC_PORT_PROP_XPIPE_MODE, FALSE));
        }

        /*TBD: disable cl73 AN & clear CL73 ability */
        if (CTC_IS_BIT_SET(option_bmp, DMPS_DS_OPTION_CLEAR_CL73) && SYS_MAC_IS_MODE_SUPPORT_CL73(port_info.serdes_info.serdes_mode))
        {
            CTC_ERROR_RETURN(sys_usw_dmps_get_mac_property_dispatch(lchip, lport, CTC_PORT_PROP_AUTO_NEG_EN, &cl73_en));
            if (cl73_en)
            {
                CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property_dispatch(lchip, lport, CTC_PORT_PROP_AUTO_NEG_EN, FALSE));
                CTC_ERROR_RETURN(sys_usw_dmps_anlt_sm_send_switch_off_msg(lchip, dport)); 
            }

            CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property_dispatch(lchip, lport, CTC_PORT_PROP_CL73_ABILITY, 0));
        }
        
        /*clear an_fec cfg */
        if (CTC_IS_BIT_SET(option_bmp, DMPS_DS_OPTION_CLEAR_AN_FEC))
        {
             CTC_ERROR_RETURN(sys_usw_dmps_db_set_an_fec(lchip, lport, (1 << CTC_PORT_FEC_TYPE_RS) | (1 << CTC_PORT_FEC_TYPE_BASER)));
        }

        /* clear unidir cfg */
        CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property_dispatch(lchip, lport, CTC_PORT_PROP_UNIDIR_EN, FALSE));

        /* recover ipg to default value */
        CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property_dispatch(lchip, lport, CTC_PORT_PROP_MAC_TX_IPG, 12));
        /* recover preamble cfg to default value */
        CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property_dispatch(lchip, lport, CTC_PORT_PROP_PREAMBLE, 8));
        /* recover padding cfg to default value */
        //CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property_dispatch(lchip, lport, CTC_PORT_PROP_PADING_EN, 1));
        CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property_dispatch(lchip, lport, CTC_PORT_PROP_CHK_CRC_EN, 1));
        CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property_dispatch(lchip, lport, CTC_PORT_PROP_STRIP_CRC_EN, 1));
        CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property_dispatch(lchip, lport, CTC_PORT_PROP_APPEND_CRC_EN, 1));

        /* CL37 related config to default value: CL37 en, parallel detect */
        if(SYS_MAC_IS_MODE_SUPPORT_CL37(port_info.serdes_info.serdes_mode))
        {
            CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property_dispatch(lchip, lport, CTC_PORT_PROP_AUTO_NEG_EN, 1));
            CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property_dispatch(lchip, lport, CTC_PORT_PROP_PAR_DET_EN, 0));
        }

        /* clear serdes-based property */
        for(idx = 0; idx < port_info.serdes_info.serdes_num; idx++)
        {
            lpbk.serdes_id = port_info.serdes_info.serdes_id[idx];
            for(lpbk_type = DMPS_SERDES_LPBK_INTERNAL; lpbk_type < DMPS_SERDES_LPBK_NONE; lpbk_type++)
            {
                lpbk.mode = lpbk_type;
                CTC_ERROR_RETURN(sys_usw_dmps_serdes_get_property(lchip, CTC_CHIP_PROP_SERDES_LOOPBACK, (void*)(&lpbk)));
                SYS_CONDITION_CONTINUE(0 == lpbk.enable);
                lpbk.enable = 0;
                CTC_ERROR_RETURN(sys_usw_dmps_serdes_set_property(lchip, CTC_CHIP_PROP_SERDES_LOOPBACK, (void*)(&lpbk)));
            }
        }
    }
    return CTC_E_NONE;
}

int32
_sys_usw_dmps_dynamic_switch_set_config(uint8 lchip, sys_dmps_ds_list_t* p_list, uint32 option_bmp)
{
    MCHIP_DMPS_CB(mac_dynamic_switch_set_config, lchip, (void*)p_list, option_bmp);
    return CTC_E_NONE;
}

/*since AT*/
int32
sys_usw_dmps_link_up_event(uint8 lchip, uint16 lport)
{
    uint32 cl37_en   = 0;
    uint32 an_mode   = 0;
    uint32 rm_link   = 0;
    uint32 mac_speed = 0;
    uint32 speed     = 0;
    uint8  gchip     = 0;
    ctc_chip_serdes_loopback_t lpbk_param = {0};
    sys_port_api_dmps_info_t port_info = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_info(lchip, lport, &port_info));

    SYS_CONDITION_RETURN(!SYS_USW_IS_NETWORK_PORT(port_info.port_type), CTC_E_NONE);

    /*1. set mac rx pkt en*/
    if(SYS_DMPS_NETWORK_PORT == port_info.port_type)
    {
        CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
        CTC_ERROR_RETURN(sys_usw_dmps_set_direction_property(lchip, CTC_MAP_LPORT_TO_GPORT(gchip, lport), CTC_PORT_DIR_PROP_MAC_EN, CTC_INGRESS, 1));
    }
    /*2. set speed for sgmii/qsgmii slaver mode*/
    SYS_CONDITION_RETURN(DRV_IS_AT(lchip), CTC_E_NONE);
    SYS_CONDITION_RETURN((!SYS_MAC_IS_MODE_SUPPORT_CL37(port_info.serdes_info.serdes_mode) || 
        (CTC_CHIP_SERDES_2DOT5G_MODE == port_info.serdes_info.serdes_mode)), CTC_E_NONE);

    /*when enable internal/local loopback,data from TX are sent back to RX, thsre's no need to do anything further.
      when enable external loopback,SerDes's state is uncertain, it's suggested to do nothing.*/
    CTC_ERROR_RETURN(_sys_usw_dmps_get_loopback_en(lchip, lport, (void*)&lpbk_param));
    SYS_CONDITION_RETURN(1 == lpbk_param.enable, CTC_E_NONE);

    CTC_ERROR_RETURN(_sys_usw_dmps_get_an_en(lchip, lport, &cl37_en));
    SYS_CONDITION_RETURN(0 == cl37_en, CTC_E_NONE);
    
    CTC_ERROR_RETURN(_sys_usw_dmps_get_an_mode(lchip, lport, &an_mode));
    SYS_CONDITION_RETURN(CTC_PORT_AUTO_NEG_MODE_SGMII_SLAVER != an_mode, CTC_E_NONE);

    CTC_ERROR_RETURN(_sys_usw_dmps_get_cl37_an_remote_status(lchip, lport,
        CTC_PORT_AUTO_NEG_MODE_SGMII_SLAVER, &speed, &rm_link));

    SYS_CONDITION_RETURN(FALSE == rm_link, CTC_E_NONE);
    
    CTC_ERROR_RETURN(_sys_usw_dmps_get_speed(lchip, lport, &mac_speed));
    SYS_CONDITION_RETURN(speed == mac_speed, CTC_E_NONE);
    
    CTC_ERROR_RETURN(_sys_usw_dmps_set_speed(lchip, lport, speed));

    return CTC_E_NONE;
}

int32
sys_usw_dmps_link_down_event(uint8 lchip, uint16 lport)
{
    sys_port_api_dmps_info_t port_info = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_info(lchip, lport, &port_info));

    SYS_CONDITION_RETURN(!SYS_USW_IS_NETWORK_PORT(port_info.port_type), CTC_E_NONE);

    /*1. set mac rx pkt disable*/
    if(SYS_DMPS_NETWORK_PORT == port_info.port_type)
    {
        uint8 gchip = 0;
        CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
        CTC_ERROR_RETURN(sys_usw_dmps_set_direction_property(lchip, CTC_MAP_LPORT_TO_GPORT(gchip, lport), CTC_PORT_DIR_PROP_MAC_EN, CTC_INGRESS, 1));
    }

    return CTC_E_NONE;
}

void
_sys_usw_dmps_reset_hw_clear_link_fsm(uint8 lchip)
{
    uint16 lport = 0;
    if(!SYS_USW_DMPS_IS_OLD_DB(lchip))
    {
        for(lport = 0; lport < SYS_USW_MAX_PORT_NUM_PER_CHIP; lport++)
        {
            (void)sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_NONREADY);
        }
    }
    return;
}

/*since AT*/
int32
_sys_usw_dmps_reset_hw_port_attr_restore(uint8 lchip, void* p_attr)
{
    uint16 dport = 0;
    sys_datapath_lport_attr_chip_recover_t* p_port_attr = (sys_datapath_lport_attr_chip_recover_t*)p_attr;
    sys_dmps_db_upt_info_t port_info = {0};

    for(dport = 0; dport < DMPS_MAX_PORT_NUM; dport++)
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_AN_FEC);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_AN_EN);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_FEC_TYPE);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_BP_ABILITY0);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_BP_ABILITY1);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_NP0_ABILITY0);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_NP0_ABILITY1);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_NP1_ABILITY0);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_NP1_ABILITY1);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_MAC_EN);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_FEC,       p_port_attr[dport].an_fec);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_EN,        p_port_attr[dport].cl73_enable);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_FEC_TYPE,     p_port_attr[dport].port_fec_val);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_BP_ABILITY0,  p_port_attr[dport].an_ability.base_ability0);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_BP_ABILITY1,  p_port_attr[dport].an_ability.base_ability1);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP0_ABILITY0, p_port_attr[dport].an_ability.np0_ability0);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP0_ABILITY1, p_port_attr[dport].an_ability.np0_ability1);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP1_ABILITY0, p_port_attr[dport].an_ability.np1_ability0);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP1_ABILITY1, p_port_attr[dport].an_ability.np1_ability1);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_MAC_EN,            p_port_attr[dport].mac_en);
    }

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_dmps_reset_hw_port_attr_recover(uint8 lchip, void* p_attr)
{
    uint16 dport = 0;
    sys_datapath_lport_attr_chip_recover_t* p_port_attr = (sys_datapath_lport_attr_chip_recover_t*)p_attr;
    sys_dmps_db_upt_info_t port_info = {0};

    for(dport = 0; dport < DMPS_MAX_PORT_NUM; dport++)
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_FEC,       p_port_attr[dport].an_fec);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_EN,        p_port_attr[dport].cl73_enable);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_FEC_TYPE,     p_port_attr[dport].port_fec_val);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_BP_ABILITY0,  p_port_attr[dport].an_ability.base_ability0);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_BP_ABILITY1,  p_port_attr[dport].an_ability.base_ability1);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP0_ABILITY0, p_port_attr[dport].an_ability.np0_ability0);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP0_ABILITY1, p_port_attr[dport].an_ability.np0_ability1);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP1_ABILITY0, p_port_attr[dport].an_ability.np1_ability0);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP1_ABILITY1, p_port_attr[dport].an_ability.np1_ability1);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_MAC_EN,            p_port_attr[dport].mac_en);
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &port_info));
    }

    return CTC_E_NONE;
}

int32
_sys_usw_dmps_reset_hw_mac_proc(uint8 lchip, void* p_data)
{
    uint16 lport        = 0;
    uint32 mac_en       = 0;
    uint32 cl73_en      = 0;
    uint32 fec_val      = 0;
    uint32 an_fec_val   = 0;
    sys_datapath_an_ability_t  an_ability = {0};
    sys_dmps_db_upt_info_t     port_info = {0};

    if(SYS_USW_DMPS_IS_OLD_DB(lchip))
    {
        CTC_ERROR_RETURN(_sys_usw_mac_reset_hw(lchip, p_data));
    }
    else
    {
        if(lchip == drv_vchip_get_pp_base(lchip))
        {
            for(lport = 0; lport < SYS_USW_MAX_PORT_NUM_PER_CHIP; lport++)
            {
                /*1. get port property db value*/
                CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
                DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, lport);
                DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_AN_FEC);
                DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_AN_EN);
                DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_FEC_TYPE);
                DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_BP_ABILITY0);
                DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_BP_ABILITY1);
                DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_NP0_ABILITY0);
                DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_NP0_ABILITY1);
                DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_NP1_ABILITY0);
                DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_NP1_ABILITY1);
                DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_MAC_EN);
                CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
                DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_FEC,       an_fec_val);
                DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_EN,        cl73_en);
                DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_FEC_TYPE,     fec_val);
                DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_BP_ABILITY0,  an_ability.base_ability0);
                DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_BP_ABILITY1,  an_ability.base_ability1);
                DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP0_ABILITY0, an_ability.np0_ability0);
                DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP0_ABILITY1, an_ability.np0_ability1);
                DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP1_ABILITY0, an_ability.np1_ability0);
                DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP1_ABILITY1, an_ability.np1_ability1);
                DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_MAC_EN,            mac_en);

                /*2. clear port property db value (in order to make recover value alternative) */
                DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_FEC,       0);
                DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_EN,        0);
                DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_FEC_TYPE,     0);
                DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_BP_ABILITY0,  0);
                DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_BP_ABILITY1,  0);
                DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP0_ABILITY0, 0);
                DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP0_ABILITY1, 0);
                DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP1_ABILITY0, 0);
                DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP1_ABILITY1, 0);
                DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_MAC_EN,            0);
                CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &port_info));

                /*3. run port property recovery*/
                /*3.1 fec config*/
                if(fec_val)
                {
                    CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property(lchip, lport, CTC_PORT_PROP_FEC_EN, SYS_DMPS_FEC_2_PORT_FEC(fec_val)));
                }
                /*3.2 an options*/
                if(cl73_en)
                {
                    CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property(lchip, lport, CTC_PORT_PROP_AUTO_NEG_EN, cl73_en));

                    MCHIP_DMPS(lchip)->mac_set_port_cl73_ability(lchip, lport, (void*)(&an_ability));

                    CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property(lchip, lport, CTC_PORT_PROP_AUTO_NEG_FEC, an_fec_val));
                }
                /*3.3 mac enable*/
                if(mac_en)
                {
                    CTC_ERROR_RETURN(sys_usw_dmps_set_mac_property(lchip, lport, CTC_PORT_PROP_MAC_EN, mac_en));
                }
            }
        }
    }

    return CTC_E_NONE;
}

int32
_sys_usw_dmps_get_ctc_cl73_ability(uint8 lchip, uint16 lport, uint32* p_ability, uint32* p_ability_ext)
{
    uint32                         loop_idx;
    uint32                         ability       = 0;
    uint32                         ability_ext   = 0;
    uint16                         dport         = 0;
    sys_dmps_db_upt_info_t         port_info     = {0};
    sys_dmps_an_ability_t          cl73_ability  = {0};
    cl73_ability_ctc_sys_map_tbl_t ability_map[] = 
    {
        /* ctc_cl73_ability                       sys_cl73_ability                                         pointer of cfg_val        */
        {CTC_PORT_CL73_10GBASE_KR,                SYS_PORT_CL73_10GBASE_KR,                                &cl73_ability.base_ability0},
        {CTC_PORT_CL73_40GBASE_KR4,               SYS_PORT_CL73_40GBASE_KR4,                               &cl73_ability.base_ability0},
        {CTC_PORT_CL73_40GBASE_CR4,               SYS_PORT_CL73_40GBASE_CR4,                               &cl73_ability.base_ability0},
        {CTC_PORT_CL73_100GBASE_KR4,              SYS_PORT_CL73_100GBASE_KR4,                              &cl73_ability.base_ability0},
        {CTC_PORT_CL73_100GBASE_CR4,              SYS_PORT_CL73_100GBASE_CR4,                              &cl73_ability.base_ability0},
        {CTC_PORT_CL73_FEC_ABILITY,               SYS_PORT_CL73_FEC_SUP,                                   &cl73_ability.base_ability1},
        {CTC_PORT_CL73_FEC_REQUESTED,             SYS_PORT_CL73_FEC_REQ,                                   &cl73_ability.base_ability1},
        {CTC_PORT_CL73_25GBASE_CRS,               SYS_PORT_CL73_25GBASE_CR_S,                              &cl73_ability.base_ability0},
        {CTC_PORT_CL73_25GBASE_KR,                (SYS_PORT_CL73_25GBASE_KR | SYS_PORT_CL73_25GBASE_KR_S), &cl73_ability.base_ability0},
        {CTC_PORT_CL73_25G_RS_FEC_REQUESTED,      SYS_PORT_CL73_25G_RS_FEC_REQ,                            &cl73_ability.base_ability1},
        {CTC_PORT_CL73_25G_BASER_FEC_REQUESTED,   SYS_PORT_CL73_25G_BASER_FEC_REQ,                         &cl73_ability.base_ability1},
        {CTC_PORT_CSTM_25GBASE_KR1,               SYS_PORT_CSTM_25GBASE_KR1,                               &cl73_ability.np1_ability0},
        {CTC_PORT_CSTM_25GBASE_CR1,               SYS_PORT_CSTM_25GBASE_CR1,                               &cl73_ability.np1_ability0},
        {CTC_PORT_CSTM_50GBASE_KR2,               SYS_PORT_CSTM_50GBASE_KR2,                               &cl73_ability.np1_ability0},
        {CTC_PORT_CSTM_50GBASE_CR2,               SYS_PORT_CSTM_50GBASE_CR2,                               &cl73_ability.np1_ability0},
        {CTC_PORT_CSTM_RS_FEC_ABILITY ,           SYS_PORT_CSTM_CL91_FEC_SUP,                              &cl73_ability.np1_ability1},
        {CTC_PORT_CSTM_BASER_FEC_ABILITY,         SYS_PORT_CSTM_CL74_FEC_SUP,                              &cl73_ability.np1_ability1},
        {CTC_PORT_CSTM_RS_FEC_REQUESTED,          SYS_PORT_CSTM_CL91_FEC_REQ,                              &cl73_ability.np1_ability1},
        {CTC_PORT_CSTM_BASER_FEC_REQUESTED,       SYS_PORT_CSTM_CL74_FEC_REQ,                              &cl73_ability.np1_ability1},
        {CTC_PORT_CL73_50GBASE_KR,                SYS_PORT_CL73_50GBASE_KR,                                &cl73_ability.base_ability1},
        {CTC_PORT_CL73_50GBASE_CR,                SYS_PORT_CL73_50GBASE_CR,                                &cl73_ability.base_ability1},
        {CTC_PORT_CL73_100GBASE_KR2,              SYS_PORT_CL73_100GBASE_KR2,                              &cl73_ability.base_ability1},
        {CTC_PORT_CL73_100GBASE_CR2,              SYS_PORT_CL73_100GBASE_KR2,                              &cl73_ability.base_ability1},
        {CTC_PORT_CL73_200GBASE_KR4,              SYS_PORT_CL73_200GBASE_KR4,                              &cl73_ability.base_ability1},
        {CTC_PORT_CL73_200GBASE_CR4,              SYS_PORT_CL73_200GBASE_CR4,                              &cl73_ability.base_ability1},
        {CTC_PORT_CSTM_400GBASE_CR8,              SYS_PORT_CSTM_400GBASE_CR8,                              &cl73_ability.np1_ability1},
        {CTC_PORT_CSTM_LF1_50GR1,                 SYS_PORT_CSTM_LF1_50GR1,                                 &cl73_ability.np1_ability1},
        {CTC_PORT_CSTM_LF2_100GR2,                SYS_PORT_CSTM_LF2_100GR2,                                &cl73_ability.np1_ability1},
        {CTC_PORT_CSTM_LF3_200GR4,                SYS_PORT_CSTM_LF3_200GR4,                                &cl73_ability.np1_ability1},
        {CTC_PORT_CSTM_LL_RS_FEC_REQ,             SYS_PORT_CSTM_LL_RS_FEC_REQ,                             &cl73_ability.np1_ability1},
    }; 
    cl73_ability_ctc_sys_map_tbl_t ability_map_ext[] = 
    {
        /* ctc_cl73_ability                       sys_cl73_ability                                         pointer of cfg_val        */
        {CTC_PORT_CL73_100GBASE_KR1,              SYS_PORT_CL73_100GBASE_KR1,                              &cl73_ability.base_ability1},
        {CTC_PORT_CL73_100GBASE_CR1,              SYS_PORT_CL73_100GBASE_CR1,                              &cl73_ability.base_ability1},
        {CTC_PORT_CL73_200GBASE_KR2,              SYS_PORT_CL73_200GBASE_KR2,                              &cl73_ability.base_ability1},
        {CTC_PORT_CL73_200GBASE_CR2,              SYS_PORT_CL73_200GBASE_CR2,                              &cl73_ability.base_ability1},
        {CTC_PORT_CL73_400GBASE_KR4,              SYS_PORT_CL73_400GBASE_KR4,                              &cl73_ability.base_ability1},
        {CTC_PORT_CL73_400GBASE_CR4,              SYS_PORT_CL73_400GBASE_CR4,                              &cl73_ability.base_ability1},
        {CTC_PORT_CL73_100G_RS_FEC_INT_REQUESTED, SYS_PORT_CL73_100G_RS_FEC_INT_REQ,                       &cl73_ability.base_ability1},
        {CTC_PORT_CSTM_800G_ETC_CR8,              SYS_PORT_CSTM_800GETC_CR8,                               &cl73_ability.np1_ability0},
        {CTC_PORT_CSTM_800G_ETC_KR8,              SYS_PORT_CSTM_800GETC_KR8,                               &cl73_ability.np1_ability0},
    }; 

    /* get cl73_ability */
    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));
    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info,        DMPS_DB_DPORT,         dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_BP_ABILITY0);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_BP_ABILITY1);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_NP0_ABILITY0);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_NP0_ABILITY1);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_NP1_ABILITY0);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_NP1_ABILITY1);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_BP_ABILITY0,  cl73_ability.base_ability0);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_BP_ABILITY1,  cl73_ability.base_ability1);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP0_ABILITY0, cl73_ability.np0_ability0);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP0_ABILITY1, cl73_ability.np0_ability1);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP1_ABILITY0, cl73_ability.np1_ability0);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP1_ABILITY1, cl73_ability.np1_ability1);

    for (loop_idx = 0; loop_idx < SYS_USW_DMPS_ARRAY_SIZE(ability_map); loop_idx++)
    {
        if ((*(ability_map[loop_idx].p_ability)) & (ability_map[loop_idx].sys_ability))
        {
            ability |= ability_map[loop_idx].ctc_ability;
        }
    }
    for (loop_idx = 0; loop_idx < SYS_USW_DMPS_ARRAY_SIZE(ability_map_ext); loop_idx++)
    {
        if ((*(ability_map_ext[loop_idx].p_ability)) & (ability_map_ext[loop_idx].sys_ability))
        {
            ability_ext |= ability_map_ext[loop_idx].ctc_ability;
        }
    }

    SYS_USW_VALID_PTR_WRITE(p_ability, ability);
    SYS_USW_VALID_PTR_WRITE(p_ability_ext, ability_ext);

    return CTC_E_NONE;
}

extern int32
_sys_usw_dmps_db_dump(uint8 lchip, uint8 db_type, sal_file_t fp);

int32
sys_usw_dmps_init(uint8 lchip, ctc_port_global_cfg_t* p_port_global_cfg)
{
    uint16 lport = 0;
    sys_port_api_dmps_info_t port_info = {0};

    if((DRV_IS_AT(lchip) && (lchip == drv_vchip_get_pp_base(lchip))) || DRV_IS_TMG(lchip))
    {
        for(lport = 0; lport < MCHIP_CAP(SYS_CAP_PORT_NUM_PER_CHIP); lport++)
        {
            SYS_CONDITION_CONTINUE((FALSE == sys_usw_dmps_db_is_lport_valid(lchip, lport))
                || (CTC_E_NONE != sys_usw_dmps_db_api_get_port_info(lchip, lport, &port_info))
                || (!SYS_USW_IS_NETWORK_PORT(port_info.port_type)));
            CTC_ERROR_RETURN(_sys_usw_dmps_set_flush_en(lchip, lport, TRUE));
        }
    }

    CTC_ERROR_RETURN(sys_usw_mac_init(lchip, p_port_global_cfg));

    (void)drv_ser_register_hw_reset_cb(lchip, DRV_SER_HW_RESET_CB_TYPE_MAC, _sys_usw_dmps_reset_hw_mac_proc);
    (void)sys_usw_mchip_set_feature_en(lchip,CTC_FEATURE_PORT);

    return CTC_E_NONE;
}

int32
sys_usw_dmps_deinit(uint8 lchip)
{
    return sys_usw_mac_deinit(lchip);
}

#ifdef EMULATION_ENV
static int32
_sys_usw_dmps_anlt_sm_set_mcu_linktrain_isr(uint8 lchip, uint8 dport)
{
    uint8  core_id    = 0;
    uint8  lane_id    = 0;
    uint8  serdes_num = 0;
    uint8  is_cpumac  = 0;    
    uint32 entry_id   = INTR_INDEX_VAL_SET;
    uint32 field_id   = 0;
    uint32 inst_id    = 0;
    uint32 value      = 1;
    uint32 index      = 0;
    uint32 cmd        = 0;
    uint32 step       = CtcHsCtlInterruptFunc1_funcIntHssTxTrainOkLane1Mcu_f - CtcHsCtlInterruptFunc1_funcIntHssTxTrainOkLane0Mcu_f;
    uint16 physic_serdes[DMPS_MAX_NUM_PER_MODULE] = {0};

    CtcHsCtlInterruptFunc1_m CtcHsCtlInterruptFunc1;
    CtcPcsCtlInterruptFunc1_m CtcPcsCtlInterruptFunc1;
    CpuMacProcInterruptFuncMcu_m CpuMacProcInterruptFuncMcu;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "lchip", lchip);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "dport", dport);

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, DMPS_DB_TYPE_PSD, &serdes_num, physic_serdes));

    if(DRV_IS_TMG(lchip))
    {
        if ((physic_serdes[0] >= 80) && (physic_serdes[0] <= 84))
        {
            is_cpumac = 1;
        }
        
        for(lane_id = 0; lane_id < serdes_num; lane_id++)
        {
            if (!is_cpumac)
            {
                inst_id  = physic_serdes[lane_id] / 8;
                index    = DRV_INS(inst_id, 0);
                step       = CtcPcsCtlInterruptFunc1_funcIntrHssL1AnltMcu_f - CtcPcsCtlInterruptFunc1_funcIntrHssL0AnltMcu_f;
                field_id = CtcPcsCtlInterruptFunc1_funcIntrHssL0AnltMcu_f + (physic_serdes[lane_id] % 4)*step;

                SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "        %-32s @ %d\n", "physic_serdes", physic_serdes[lane_id]);

                /* #2, read HW table */
                cmd = DRV_IOR(CtcPcsCtlInterruptFunc1_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &CtcPcsCtlInterruptFunc1));
                
                /* #3. modify field value */
                value = 1;
                DRV_IOW_FIELD(lchip, CtcPcsCtlInterruptFunc1_t, field_id, &value, &CtcPcsCtlInterruptFunc1);

                /* #4, write HW table */
                cmd = DRV_IOW(CtcPcsCtlInterruptFunc1_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &CtcPcsCtlInterruptFunc1));
            }
            else
            {
                inst_id  = 0;
                index    = DRV_INS(inst_id, 0);
                step       = CpuMacProcInterruptFuncMcu_funcIntrHssL1AnltMcu_f - CpuMacProcInterruptFuncMcu_funcIntrHssL0AnltMcu_f;
                field_id = CpuMacProcInterruptFuncMcu_funcIntrHssL0AnltMcu_f + (physic_serdes[lane_id] % 4)*step;
                
                SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "        %-32s @ %d\n", "physic_serdes", physic_serdes[lane_id]);
                
                /* #2, read HW table */
                cmd = DRV_IOR(CpuMacProcInterruptFuncMcu_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &CpuMacProcInterruptFuncMcu));
                
                /* #3. modify field value */
                value = 1;
                DRV_IOW_FIELD(lchip, CpuMacProcInterruptFuncMcu_t, field_id, &value, &CpuMacProcInterruptFuncMcu);
                
                /* #4, write HW table */
                cmd = DRV_IOW(CpuMacProcInterruptFuncMcu_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &CpuMacProcInterruptFuncMcu));
            }
        }
    }
    else
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_core_id_by_dport(lchip, dport, &core_id));

        for(lane_id = 0; lane_id < serdes_num; lane_id++)
        {
            inst_id  = physic_serdes[lane_id] / 4;
            index    = DRV_INS(inst_id, entry_id);
            field_id = CtcHsCtlInterruptFunc1_funcIntHssTxTrainOkLane0Mcu_f + (physic_serdes[lane_id] % 4)*step;

            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "        %-32s @ %d\n", "physic_serdes", physic_serdes[lane_id]);

            cmd = DRV_IOR(CtcHsCtlInterruptFunc1_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DMPS_DRV_IOCTL_CORE(lchip, index, core_id, cmd, &CtcHsCtlInterruptFunc1));

            DRV_IOW_FIELD(lchip, CtcHsCtlInterruptFunc1_t, field_id, &value, &CtcHsCtlInterruptFunc1);

            cmd = DRV_IOW(CtcHsCtlInterruptFunc1_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DMPS_DRV_IOCTL_CORE(lchip, index, core_id, cmd, &CtcHsCtlInterruptFunc1));
        }
    }

    return CTC_E_NONE;
}
#endif

int32
sys_usw_dmps_anlt_sm_dynamic_switch(uint8 lchip, uint16 lport, uint8 pcs_mode)
{
    uint8  mode_old    = CTC_CHIP_SERDES_NONE_MODE;
    uint32 option_bmp  = 0;
    sys_dmps_ds_list_t ds_list = {0};
    ctc_port_if_mode_t if_mode = {0};
    
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_ifmode(lchip, lport, &mode_old));
    SYS_CONDITION_RETURN(mode_old == pcs_mode, CTC_E_NONE);
    
    SYS_DMPS_GET_IFMODE_BY_SERDES_MODE(if_mode.speed, if_mode.interface_type, pcs_mode);

    CTC_BIT_UNSET(option_bmp, DMPS_DS_OPTION_SERDES_SWITCH);
    CTC_BIT_UNSET(option_bmp, DMPS_DS_OPTION_CLEAR_MAC);
    CTC_BIT_UNSET(option_bmp, DMPS_DS_OPTION_CLEAR_CL73);
    CTC_BIT_UNSET(option_bmp, DMPS_DS_OPTION_CLEAR_AN_FEC);
    CTC_ERROR_RETURN(_sys_usw_dmps_dynamic_switch_get_list(lchip, lport, &if_mode, &ds_list));
    CTC_ERROR_RETURN(_sys_usw_dmps_dynamic_switch_set_property_clear(lchip, &ds_list, option_bmp));
    CTC_ERROR_RETURN(_sys_usw_dmps_dynamic_switch_set_config(lchip, &ds_list, option_bmp));

    return CTC_E_NONE;
}

#if 0
int32
_sys_usw_dmps_anlt_sm_send_switch_done_msg(uint8 lchip, uint16 dport)
{
    struct data_struct_s
    {
        uint32 dport;
        sys_dmps_an_ability_t cl73_ability;
    };
    typedef struct data_struct_s data_struct_t;
    uint8  mcu_id           = 0x0;
    data_struct_t send_data = {0x0};
    sys_dmps_db_upt_info_t port_info  = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "lchip", lchip);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "dport", dport);
    
    if (NULL == MCHIP_DMPS(lchip)->anlt_sm_get_mcu_id_by_dport)
    {
        return CTC_E_NOT_SUPPORT;
    } 
    CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->anlt_sm_get_mcu_id_by_dport(lchip, dport, &mcu_id));

    send_data.dport        = dport;
    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_BP_ABILITY0, 0);
    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_BP_ABILITY1, 0);
    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP0_ABILITY0, 0);
    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP0_ABILITY1, 0);
    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP1_ABILITY0, 0);
    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP1_ABILITY1, 0);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));    
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_BP_ABILITY0,  send_data.cl73_ability.base_ability0);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_BP_ABILITY1,  send_data.cl73_ability.base_ability1);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP0_ABILITY0, send_data.cl73_ability.np0_ability0);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP0_ABILITY1, send_data.cl73_ability.np0_ability1);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP1_ABILITY0, send_data.cl73_ability.np1_ability0);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_NP1_ABILITY1, send_data.cl73_ability.np1_ability1);

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "        %-32s @ %d\n", "mcu_id", mcu_id);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "        %-32s @ %d\n", "dport", dport);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "        %-32s @ 0x%08x\n", "base_ability0", send_data.cl73_ability.base_ability0);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "        %-32s @ 0x%08x\n", "base_ability1", send_data.cl73_ability.base_ability1);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "        %-32s @ 0x%08x\n", "np0_ability0",  send_data.cl73_ability.np0_ability0);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "        %-32s @ 0x%08x\n", "np0_ability1",  send_data.cl73_ability.np0_ability1);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "        %-32s @ 0x%08x\n", "np1_ability0",  send_data.cl73_ability.np1_ability0);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "        %-32s @ 0x%08x\n", "np1_ability0",  send_data.cl73_ability.np1_ability0);

#if(1 == SDK_WORK_PLATFORM)
        return CTC_E_NONE;
#endif
    CTC_ERROR_RETURN(sys_usw_dmps_msg_send(lchip, mcu_id, SYS_DMPS_MSG_CODE_ASYNC_C2M_ANLT_EN, sizeof(data_struct_t), &send_data));

    return CTC_E_NONE;
}
#endif


static int32
_sys_usw_dmps_anlt_sm_msg_recv_cb_status_sync(uint8 lchip, uint8 mcu_id, uint32 msg_id, void *p_in_data, void *p_out)
{  
    uint8  mac_en           = 0x0;
    uint8  an_en            = 0x0;
    uint8  src_if_mode      = 0x0;
    uint8  dst_if_mode      = 0x0;
    uint8  dst_serdes_num   = 0x0;
    uint8  src_serdes_num   = 0x0;
    uint16 lport            = 0x0;
    uint8  serdes_num       = 0x0;
    uint8  loop_idx         = 0x0;
    int32  ret              = 0x0;
    sys_dmps_db_upt_info_t port_info  = {0};
    ctc_chip_serdes_ctle_t ctle_cfg   = {0};
    uint16 physic_serdes[DMPS_MAX_NUM_PER_MODULE] = {0};
    dmps_msg_ds_anlt_status_sync_t*  p_data  = (dmps_msg_ds_anlt_status_sync_t*)p_in_data;

    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "lchip", lchip);
    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "mcu_id", mcu_id);
    
    if(NULL == MCHIP_DMPS(lchip)->anlt_sm_set_fec)
    {
        return CTC_E_NOT_SUPPORT;
    } 

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, p_data->dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_AN_EN);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_MAC_EN);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_EN, an_en);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_MAC_EN, mac_en);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE, src_if_mode);

    if ((!mac_en) || (!an_en))
    {
        return CTC_E_NONE;
    }

    SYS_MCU_SERDES_MODE_TO_CTC_SERDES_MODE(p_data->if_mode, dst_if_mode)
    
    lport = sys_usw_dmps_db_get_lport_by_dport(lchip, p_data->dport);

    /* Happen AN_Good Event */
    if (DMPS_ANLT_SM_STATUS_MSG_TYPE_AN_OK == p_data->status)
    {
        SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "port %3d AN OK\n", p_data->dport);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_AN_OK, 1);
        
        SYS_DMPS_GET_SERDES_NUM_BY_MODE(src_if_mode, src_serdes_num);
        SYS_DMPS_GET_SERDES_NUM_BY_MODE(dst_if_mode, dst_serdes_num);

        if (src_serdes_num != dst_serdes_num)
        {
#ifdef EMULATION_ENV
            CTC_ERROR_RETURN(_sys_usw_dmps_anlt_sm_set_mcu_linktrain_isr(lchip, p_data->dport));
#endif  
            return CTC_E_NONE;
        }
        
        /* 1. Dynamic Swicth*/
        if (src_if_mode != dst_if_mode)
        {
            CTC_ERROR_RETURN(sys_usw_dmps_anlt_sm_dynamic_switch(lchip, lport, dst_if_mode));
        }

        /* 2. Configure FEC */
        if (SYS_DMPS_FEC_TYPE_MAX != p_data->fec_type)
        {
            CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->anlt_sm_set_fec(lchip, p_data->dport, p_data->fec_type));
        }
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_AN_HCD, 
                     ((uint16)((dst_if_mode << 8) & 0xff00) | (uint16)(p_data->fec_type & 0x00ff)));
        
#ifdef EMULATION_ENV
        CTC_ERROR_RETURN(_sys_usw_dmps_anlt_sm_set_mcu_linktrain_isr(lchip, p_data->dport));
#endif  
    }
    /* Happen ANLT_DONE Event */
    else if (DMPS_ANLT_SM_STATUS_MSG_TYPE_ANLT_OK == p_data->status)
    {
        SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "port %3d ANLT OK\n", p_data->dport);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LT_DONE, 1);

        CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, p_data->dport, DMPS_DB_TYPE_PSD, &serdes_num, physic_serdes));
        /*do ctle auto (Arctic CS)*/
        if (DRV_IS_AT(lchip) && (physic_serdes[0] >= 16 && physic_serdes[0] <= 143))
        {
            ctle_cfg.auto_en = 1;
            for (loop_idx = 0; loop_idx < serdes_num; loop_idx ++)
            {
                ctle_cfg.serdes_id = physic_serdes[loop_idx];
                ret = sys_usw_dmps_serdes_set_property(lchip, CTC_CHIP_PROP_SERDES_CTLE, &ctle_cfg);
                if (CTC_E_NONE != ret)
                {
                    ret = sys_usw_dmps_serdes_set_property(lchip, CTC_CHIP_PROP_SERDES_CTLE, &ctle_cfg);
                }
            }
        }
        
        CTC_ERROR_RETURN(_sys_usw_dmps_set_mac_en(lchip, lport, TRUE, FALSE));
    }
    /* Happen LINK_UP_TIMEOUT Event */
    else if (DMPS_ANLT_SM_STATUS_MSG_TYPE_LINK_UP_TIMEOUT == p_data->status)
    {
        SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "port %3d ANLT link_up timeout\n", p_data->dport);
        CTC_ERROR_RETURN(_sys_usw_dmps_set_mac_en(lchip, lport, FALSE, FALSE));
        CTC_ERROR_RETURN(sys_usw_dmps_anlt_sm_send_restart_an_msg(lchip, p_data->dport));
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_AN_RESTART, 1);
    }
    /* Happen RESTART_ANLT Event when link down */
    else if (DMPS_ANLT_SM_STATUS_MSG_TYPE_RESTART_ANLT == p_data->status)
    {
        SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "port %d restart anlt when link down", p_data->dport);
        CTC_ERROR_RETURN(_sys_usw_dmps_set_mac_en(lchip, lport, FALSE, FALSE));
        CTC_ERROR_RETURN(sys_usw_dmps_anlt_sm_send_restart_an_msg(lchip, p_data->dport));
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_AN_RESTART, 3);
    }
    
    return CTC_E_NONE;
}

int32
sys_usw_dmps_get_mac_stats(uint8 lchip, uint32 block_id, sys_usw_dmps_mac_stats_t* p_mac_stats)
{
    int32 ret = 0;
    if(MCHIP_DMPS(lchip)->mcu_get_mac_stats)
    {
        ret = MCHIP_DMPS(lchip)->mcu_get_mac_stats(lchip, block_id, p_mac_stats);
    }
    else return CTC_E_INVALID_PTR;

    return ret;
}

int32
sys_usw_dmps_clear_mac_stats(uint8 lchip, uint32 block_id, uint8 dir)
{
    int32 ret = 0;
    if(MCHIP_DMPS(lchip)->mcu_clear_mac_stats)
    {
        ret = MCHIP_DMPS(lchip)->mcu_clear_mac_stats(lchip, block_id, dir);
    }
    else return CTC_E_INVALID_PTR;

    return ret;
}

#define __SYS_DMPS_MSG_API__

#define DMPS_MSG_HEAD_WORD   4

static int32 
_sys_usw_dmps_msg_write_async_msg(uint8 lchip, uint8 mcu_id, uint32 priority, sys_usw_dmps_mcu_msg_struct_t* p_message)
{  
    uint16  message_len   = 0;
    uint32  idx           = 0;
    uint32  timeout       = 2500;
    uint32  send_ptr      = 0;
    uint32  recv_ptr      = 0;
    uint32  val32         = 0;
    uint32  addr          = 0;
    uint32  data_len      = 0;
    uint32* p_val32       = (uint32*)p_message->p_data;
    uint32  idle_size     = 0;
    uint32  send_ptr_addr = 0;
    uint32  recv_ptr_addr = 0;
    uint32  buf_len       = 0;
    uint32  base_addr     = 0;
    uint32  msg_type      = 0;
    sys_dmps_db_msg_handle_t* p_handle = NULL;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_msg_handle(lchip, &p_handle));
    CTC_PTR_VALID_CHECK(p_handle);

    send_ptr_addr = p_handle->p_c2m_buf[priority].send_ptr_addr;
    recv_ptr_addr = p_handle->p_c2m_buf[priority].recv_ptr_addr;
    buf_len       = p_handle->p_c2m_buf[priority].buf_len;
    base_addr     = p_handle->p_c2m_buf[priority].base_addr;

    CTC_ERROR_RETURN(p_handle->get_header_field(p_message->header, SYS_DMPS_MSG_HEADER_DATA_LEN, &data_len));
    CTC_ERROR_RETURN(p_handle->get_header_field(p_message->header, SYS_DMPS_MSG_HEADER_TYPE,     &msg_type));
    message_len = data_len + p_handle->header_len;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"lchip:%d, mcu_id:%d, priority:%d, msg_type:%d, data_len:%d\n", lchip, mcu_id, priority, msg_type, data_len);

    CTC_ERROR_RETURN(p_handle->read(lchip, mcu_id, send_ptr_addr, 0x0, &send_ptr));
    if ((send_ptr + message_len) > buf_len)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "           Ring Buf go to Start.\n");
    }

    /* waiting buffer */
    while(-- timeout)
    {   
        /* read shared memory, get ptr_head  & ptr_tail */
        CTC_ERROR_RETURN(p_handle->read(lchip, mcu_id, send_ptr_addr, 0x0, &send_ptr));
        CTC_ERROR_RETURN(p_handle->read(lchip, mcu_id, recv_ptr_addr, 0x0, &recv_ptr));

        idle_size = (send_ptr >= recv_ptr) ? (buf_len - (send_ptr - recv_ptr)) : (recv_ptr - send_ptr);

        if (message_len > idle_size)
        {            
            sal_task_sleep(1);
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "           mcu_id@%d, message_len > idle_size. Please Waiting MCU Process\n", mcu_id);
            continue;
        }
        
        break;
    }
  
    if (0 == timeout)
    { 
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Send Asyn Msg Timeout. | %s()@%d\n", __FUNCTION__, __LINE__);       
        return CTC_E_HW_TIME_OUT;
    }

    /* write message header to shared memory */
    p_val32 = (uint32*)p_message->header;
    for (idx = 0; idx < p_handle->header_len / sizeof(uint32); idx ++)
    {
        val32 = *(p_val32 + idx);
        addr = base_addr + send_ptr;
        CTC_ERROR_RETURN(p_handle->write(lchip, mcu_id, addr, 0x0, val32));
        send_ptr = (send_ptr + sizeof(uint32)) % buf_len;
    }  

    /* write message data to shared memory */
    p_val32 = (uint32*)p_message->p_data;
    for (idx = 0; idx < data_len / sizeof(uint32); idx ++)
    {
        val32 = *(p_val32 + idx);
        addr = base_addr + send_ptr;
        CTC_ERROR_RETURN(p_handle->write(lchip, mcu_id, addr, 0x0, val32));
        send_ptr = (send_ptr + sizeof(uint32)) % buf_len;
    }

    /* write send_ptr to shared memory */
    CTC_ERROR_RETURN(p_handle->write(lchip, mcu_id, send_ptr_addr, 0x0, send_ptr));

    /* gen intr to mcu */
    CTC_ERROR_RETURN(p_handle->gen_intr(lchip, mcu_id));

    return CTC_E_NONE;    
}

static int32 
_sys_usw_dmps_msg_write_sync_msg(uint8 lchip, uint8 mcu_id, sys_usw_dmps_mcu_msg_struct_t* p_message)
{  
    uint32  idx           = 0;
    uint32  send_ptr      = 0;
    uint32  val32         = 0;
    uint32  addr          = 0;
    uint32  data_len      = 0;
    uint32* p_val32       = NULL;
    uint32  base_addr     = 0;
    uint32  msg_type      = 0;
    sys_dmps_db_msg_handle_t* p_handle = NULL;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_msg_handle(lchip, &p_handle));
    CTC_PTR_VALID_CHECK(p_handle);

    base_addr = p_handle->sync_buf_addr;
    CTC_ERROR_RETURN(p_handle->get_header_field(p_message->header, SYS_DMPS_MSG_HEADER_DATA_LEN, &data_len));
    CTC_ERROR_RETURN(p_handle->get_header_field(p_message->header, SYS_DMPS_MSG_HEADER_TYPE,     &msg_type));
    
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"lchip:%d, mcu_id:%d, msg_type:%d, data_len:%d\n", lchip, mcu_id, msg_type, data_len);

    /* write message header to shared memory */
    p_val32 = (uint32*)p_message->header;
    for (idx = 0; idx < p_handle->header_len / sizeof(uint32); idx ++)
    {
        val32 = *(p_val32 + idx);
        addr = base_addr + send_ptr;
        CTC_ERROR_RETURN(p_handle->write(lchip, mcu_id, addr, 0x0, val32));
        send_ptr = send_ptr + sizeof(uint32);
    }  

    /* write message data to shared memory */
    p_val32 = (uint32*)p_message->p_data;
    for (idx = 0; idx < data_len / sizeof(uint32); idx ++)
    {
        val32 = *(p_val32 + idx);
        addr = base_addr + send_ptr;
        CTC_ERROR_RETURN(p_handle->write(lchip, mcu_id, addr, 0x0, val32));
        send_ptr = send_ptr + sizeof(uint32);
    }

    CTC_ERROR_RETURN(p_handle->write(lchip, mcu_id, MCU_GLB_INFO_SYN_STATUS, 0x0, SYS_DMPS_MSG_SYNC_STATUS_PROCESS));
   
    /* when idle_size is equal to buf_len, then gen intr to mcu */
    CTC_ERROR_RETURN(p_handle->gen_intr(lchip, mcu_id));

    return CTC_E_NONE;    
}

static int32 
_sys_usw_dmps_msg_send_sync_msg(uint8 lchip, uint8 mcu_id, sys_usw_dmps_mcu_msg_struct_t* p_msg, void* p_out)
{
    int32  ret              = 0;
    uint32 idx              = 0;
    uint32 msg_type         = 0;
    uint32 msg_id           = 0;
    uint32 data_len         = 0;
    uint32 rp_data_len      = 0;
    uint32 recv_ptr         = sizeof(uint32);
    uint32 sync_status      = 0;
    uint32  timeout         = 2500;
    uint32* p_val32         = NULL;
    sys_dmps_db_msg_handle_t* p_handle = NULL;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_msg_handle(lchip, &p_handle));
    CTC_PTR_VALID_CHECK(p_handle);

    CTC_ERROR_RETURN(p_handle->get_header_field(p_msg->header, SYS_DMPS_MSG_HEADER_DATA_LEN, &data_len));
    CTC_ERROR_RETURN(p_handle->get_header_field(p_msg->header, SYS_DMPS_MSG_HEADER_TYPE,     &msg_type));

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"lchip:%d, mcu_id:%d, msg_type:%d, data_len:%d\n", lchip, mcu_id, msg_type, data_len);

    if ((p_handle->header_len +  data_len) > p_handle->sync_buf_len)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% INVALID PARAM. | %s()@%d\n", __FUNCTION__, __LINE__);  
        return CTC_E_INVALID_PARAM;
    }

    /* Fill message id */
    msg_id = p_handle->cur_sync_id;
    CTC_ERROR_RETURN(p_handle->set_header_field(p_msg->header, SYS_DMPS_MSG_HEADER_ID, msg_id));
    p_handle->cur_sync_id = (msg_id + 1) % p_handle->msg_id_num;

    /* Write message */
    CTC_ERROR_RETURN(_sys_usw_dmps_msg_write_sync_msg(lchip, mcu_id, p_msg));

    /* Waiting Reponse */
    while(--timeout)
    {
        CTC_ERROR_RETURN(p_handle->read(lchip, mcu_id, MCU_GLB_INFO_SYN_STATUS, 0x0, &sync_status));
        
        if (SYS_DMPS_MSG_SYNC_STATUS_IDLE == sync_status)
        {
            break;
        }
        sal_task_sleep(1);
    }
    
    if (0 == timeout)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Send Sync Msg Timeout. | %s()@%d\n", __FUNCTION__, __LINE__); 
        return CTC_E_HW_TIME_OUT;
    }

    /* Get Reponse Data Length */
    CTC_ERROR_RETURN(p_handle->read(lchip, mcu_id, p_handle->sync_buf_addr, 0x0, &rp_data_len));
    if (rp_data_len != p_handle->registers[msg_type].rps_data_size)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Msg Type %u Get Reponse Data Length %u isn't equal to %u. | %s()@%d\n", \
                                msg_type, rp_data_len, p_handle->registers[msg_type].rps_data_size, __FUNCTION__, __LINE__); 
        return CTC_E_HW_FAIL;
    }

    /*  Get Reponse Data */
    if (0 != rp_data_len)
    {
        p_val32 = (uint32*)mem_malloc(MEM_DMPS_MODULE, rp_data_len);
        if(NULL == p_val32)
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% NO MEMORY. | %s()@%d\n", __FUNCTION__, __LINE__); 
            return CTC_E_NO_MEMORY;
        }
        for (idx = 0; idx < rp_data_len / sizeof(uint32); idx ++)
        {
            CTC_ERROR_GOTO(p_handle->read(lchip, mcu_id, p_handle->sync_buf_addr + recv_ptr, 0x0, p_val32 + idx), ret, RELEASE_PTR_RETURN);
            recv_ptr = recv_ptr + sizeof(uint32);
        }
    }
    /* Process message */
    if (NULL != p_handle->registers[msg_type].recv_cb)
    {
        CTC_ERROR_GOTO(p_handle->registers[msg_type].recv_cb(lchip, mcu_id, msg_id, (void*)p_val32, p_out), ret, RELEASE_PTR_RETURN);
    }

RELEASE_PTR_RETURN:
    if (0 != rp_data_len)
    {
        mem_free(p_val32);
    }

    return ret;
}

int32
_sys_usw_dmps_msg_recv_async_msg(uint8 lchip, uint8 mcu_id, uint8 priority)
{
    int32   ret           = 0;
    uint32  idx           = 0;
    uint32  msg_type      = 0;
    uint32  msg_id        = 0;
    uint32  recv_ptr      = 0;
    uint32* p_val32       = NULL;
    uint32  recv_ptr_addr = 0;
    uint32  base_addr     = 0;
    uint32  buf_len       = 0;
    uint32  data_len      = 0;
    uint32  msg_header[DMPS_MSG_HEAD_WORD];
    sys_usw_dmps_mcu_msg_struct_t  message = {NULL, NULL};
    sys_dmps_db_msg_handle_t* p_handle = NULL;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"lchip:%d, mcu_id:%d, priority:%d\n", lchip, mcu_id, priority);

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_msg_handle(lchip, &p_handle));
    CTC_PTR_VALID_CHECK(p_handle);

    recv_ptr_addr = p_handle->p_m2c_buf[priority].recv_ptr_addr;
    base_addr     = p_handle->p_m2c_buf[priority].base_addr;
    buf_len       = p_handle->p_m2c_buf[priority].buf_len;

    /* Get Message Header */
    CTC_ERROR_RETURN(p_handle->read(lchip, mcu_id, recv_ptr_addr, 0x0, &recv_ptr));
    message.header = (void*)msg_header;
    for (idx = 0; idx < p_handle->header_len / sizeof(uint32); idx ++)
    {
        CTC_ERROR_RETURN(p_handle->read(lchip, mcu_id, base_addr + recv_ptr, 0x0, msg_header + idx));
        recv_ptr =(recv_ptr + sizeof(uint32)) % buf_len;
    }

    CTC_ERROR_RETURN(p_handle->get_header_field(message.header, SYS_DMPS_MSG_HEADER_DATA_LEN, &data_len));

    /* Get Message PayLoad */
    if (0 != data_len)
    {
        message.p_data = (void*)mem_malloc(MEM_DMPS_MODULE, data_len);
        if(NULL == message.p_data)
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% NO MEMORY. | %s()@%d\n", __FUNCTION__, __LINE__); 
            return CTC_E_NO_MEMORY;
        }
        p_val32 = (uint32*)message.p_data;
        for (idx = 0; idx < data_len / sizeof(uint32); idx ++)
        {
            CTC_ERROR_GOTO(p_handle->read(lchip, mcu_id, base_addr + recv_ptr, 0x0, p_val32 + idx), ret, RELEASE_PTR_RETURN);
            recv_ptr = (recv_ptr + sizeof(uint32)) % buf_len;
        }
    }

    CTC_ERROR_GOTO(p_handle->get_header_field(message.header, SYS_DMPS_MSG_HEADER_TYPE, &msg_type), ret, RELEASE_PTR_RETURN);
    CTC_ERROR_GOTO(p_handle->get_header_field(message.header, SYS_DMPS_MSG_HEADER_ID,   &msg_id), ret, RELEASE_PTR_RETURN);

    /* Process message */
    if (NULL != p_handle->registers[msg_type].recv_cb)
    {
        CTC_ERROR_GOTO(p_handle->registers[msg_type].recv_cb(lchip, mcu_id, msg_id, message.p_data, NULL), ret, RELEASE_PTR_RETURN);
    }

    /* Modify recv_ptr */
    CTC_ERROR_GOTO(p_handle->write(lchip, mcu_id, recv_ptr_addr, 0x0, recv_ptr), ret, RELEASE_PTR_RETURN);

RELEASE_PTR_RETURN:
    if (0 != data_len)
    {
        mem_free(message.p_data);
    }
    
    return ret;
}

int32
_sys_usw_dmps_msg_is_recv(uint8 lchip, uint8 mcu_id, uint8* p_is_recv_msg, uint8* p_priority)
{ 
    uint8  priority         = 0;
    uint32 send_ptr         = 0;
    uint32 recv_ptr         = 0;
    sys_dmps_db_msg_handle_t* p_handle = NULL;
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_msg_handle(lchip, &p_handle));
    CTC_PTR_VALID_CHECK(p_handle);
    
    /* read shared memory by priority, get ptr_head */
    for (priority = 0; priority < p_handle->priority_num; priority ++)
    {
        CTC_ERROR_RETURN(p_handle->read(lchip, mcu_id, p_handle->p_m2c_buf[priority].send_ptr_addr, 0x0, &send_ptr));
        CTC_ERROR_RETURN(p_handle->read(lchip, mcu_id, p_handle->p_m2c_buf[priority].recv_ptr_addr, 0x0, &recv_ptr));

        if (send_ptr != recv_ptr)
        {
            *p_is_recv_msg = TRUE;
            *p_priority    = priority;
            break;
        }
    }

    if (p_handle->priority_num == priority)
    {
        *p_is_recv_msg = FALSE;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_dmps_msg_register_rx_cb(uint8 lchip, uint32 msg_type, uint8 rps_data_size, void* recv_cb)
{
    CTC_ERROR_RETURN(sys_usw_dmps_db_set_msg_registers_tab(lchip, msg_type, SYS_DMPS_MSG_BUF_PRIORITY_MAX, rps_data_size, recv_cb));

    return CTC_E_NONE;
}

int32
_sys_usw_dmps_msg_register_tx_pri(uint8 lchip, uint32 msg_type, uint32 priority)
{
    CTC_ERROR_RETURN(sys_usw_dmps_db_set_msg_registers_tab(lchip, msg_type, priority, 0, NULL));

    return CTC_E_NONE;
}

/******************************************************************************************/

/* 
 * +------------------------------+ 0 K
 * +          Glb Info            +
 * +------------------------------+ 2 K
 * +          Log Info            +
 * +------------------------------+ a K
 * +          Sync Buf            +
 * +------------------------------+ b K
 * +          ASync Buf           + 
 * +------------------------------+ c K
*/
int32
sys_usw_dmps_msg_init(uint8 lchip, void* p_data)
{
    uint8  mcu_id   = 0x0;
    uint32 tmp_addr = 0x0;
    uint32 buf_len  = 0x0;
    uint32 priority = 0;
    sys_dmps_db_msg_init_info_t* p_init_info = (sys_dmps_db_msg_init_info_t*)p_data;
    sys_dmps_db_msg_handle_t  tmp_handle;

    CTC_PTR_VALID_CHECK(p_init_info->read);
    CTC_PTR_VALID_CHECK(p_init_info->write);
    CTC_PTR_VALID_CHECK(p_init_info->gen_intr);
    CTC_PTR_VALID_CHECK(p_init_info->get_header_field);
    CTC_PTR_VALID_CHECK(p_init_info->set_header_field);
    
    if (p_init_info->priority_num > SYS_DMPS_DB_MSG_PRI_NUM_MAX)
    {
        return CTC_E_INVALID_PARAM;
    }

    sal_memset(&tmp_handle, 0x0, sizeof(sys_dmps_db_msg_handle_t));

    tmp_handle.read             = p_init_info->read;
    tmp_handle.write            = p_init_info->write;
    tmp_handle.gen_intr         = p_init_info->gen_intr;
    tmp_handle.get_header_field = p_init_info->get_header_field;
    tmp_handle.set_header_field = p_init_info->set_header_field;

    tmp_handle.header_len    = p_init_info->header_len;
    tmp_handle.priority_num  = p_init_info->priority_num;
    tmp_handle.msg_id_num    = p_init_info->msg_id_num;
    tmp_handle.log_addr      = p_init_info->log_addr;
    tmp_handle.log_len       = p_init_info->log_len;
    tmp_handle.sync_buf_addr = p_init_info->buf_addr;
    tmp_handle.sync_buf_len  = p_init_info->sync_buf_len;
    sal_memcpy(&tmp_handle.mcu_info, &p_init_info->mcu_info, sizeof(sys_dmps_db_msg_mcu_info_t)); 

    tmp_addr = p_init_info->buf_addr + p_init_info->sync_buf_len;

    sal_memset(tmp_handle.p_c2m_buf, 0x0, sizeof(sys_dmps_db_msg_buf_t)*SYS_DMPS_DB_MSG_PRI_NUM_MAX);
    sal_memset(tmp_handle.p_m2c_buf, 0x0, sizeof(sys_dmps_db_msg_buf_t)*SYS_DMPS_DB_MSG_PRI_NUM_MAX);
    
    buf_len = p_init_info->async_buf_len;
    for (priority = 0; priority < p_init_info->priority_num; priority ++)
    {
        tmp_handle.p_c2m_buf[priority].buf_len       = buf_len;
        tmp_handle.p_c2m_buf[priority].recv_ptr_addr = tmp_addr + sizeof(uint32)*0;
        tmp_handle.p_c2m_buf[priority].send_ptr_addr = tmp_addr + sizeof(uint32)*1;
        tmp_handle.p_c2m_buf[priority].base_addr     = tmp_addr + sizeof(uint32)*2;
        tmp_addr += sizeof(uint32) * 2 + buf_len;
    }

    for (priority = 0; priority < p_init_info->priority_num; priority ++)
    {
        tmp_handle.p_m2c_buf[priority].buf_len       = buf_len;
        tmp_handle.p_m2c_buf[priority].recv_ptr_addr = tmp_addr + sizeof(uint32)*0;
        tmp_handle.p_m2c_buf[priority].send_ptr_addr = tmp_addr + sizeof(uint32)*1;
        tmp_handle.p_m2c_buf[priority].base_addr     = tmp_addr + sizeof(uint32)*2;
        tmp_addr += sizeof(uint32) * 2 + buf_len;
    }

    /* init mcu mate data */    
    for (mcu_id = 0; mcu_id < tmp_handle.mcu_info.max_mcu_num; mcu_id ++)
    {
        if (!CTC_BMP_ISSET(tmp_handle.mcu_info.mcu_bmp, mcu_id))
        {
            continue;
        }
        tmp_handle.write(lchip, mcu_id, MCU_GLB_INFO_MCU_ID,            0x0, mcu_id);
        tmp_handle.write(lchip, mcu_id, MCU_GLB_INFO_DBG_LOG_CTL,       0x0, 0x1a);
        tmp_handle.write(lchip, mcu_id, MCU_GLB_INFO_DBG_LOG_BASE_ADDR, 0x0, p_init_info->log_addr);
        tmp_handle.write(lchip, mcu_id, MCU_GLB_INFO_DBG_LOG_LEN,       0x0, p_init_info->log_len);
        tmp_handle.write(lchip, mcu_id, MCU_GLB_INFO_MSG_PRIORITY_NUM,  0x0, p_init_info->priority_num);
        tmp_handle.write(lchip, mcu_id, MCU_GLB_INFO_MSG_ID_NUM,        0x0, p_init_info->msg_id_num);
        tmp_handle.write(lchip, mcu_id, MCU_GLB_INFO_MSG_BUF_BASE_ADDR, 0x0, p_init_info->buf_addr);
        tmp_handle.write(lchip, mcu_id, MCU_GLB_INFO_MSG_SYNC_BUF_LEN,  0x0, p_init_info->sync_buf_len);
        tmp_handle.write(lchip, mcu_id, MCU_GLB_INFO_MSG_ASYNC_BUF_LEN, 0x0, p_init_info->async_buf_len);
    }

    CTC_ERROR_RETURN(sys_usw_dmps_db_set_msg_handle(lchip, &tmp_handle));

    return CTC_E_NONE; 
}

int32 
sys_usw_dmps_msg_sync_send(uint8 lchip, uint8 mcu_id, uint32 msg_type, uint32 data_len, void* p_in, void* p_out)
{
    uint32 msg_header[DMPS_MSG_HEAD_WORD];
    sys_usw_dmps_mcu_msg_struct_t message = {NULL, NULL};
    sys_dmps_db_msg_handle_t* p_handle = NULL;

#if(1 == SDK_WORK_PLATFORM)
    return CTC_E_NONE;
#endif

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_msg_handle(lchip, &p_handle));
    CTC_PTR_VALID_CHECK(p_handle);
    if (!CTC_BMP_ISSET(p_handle->mcu_info.mcu_bmp, mcu_id))
    {
        return CTC_E_NONE;
    }

    CTC_ERROR_RETURN(p_handle->set_header_field((void*)msg_header, SYS_DMPS_MSG_HEADER_TYPE,     msg_type));
    CTC_ERROR_RETURN(p_handle->set_header_field((void*)msg_header, SYS_DMPS_MSG_HEADER_DATA_LEN, data_len));

    message.header = (void*)msg_header;
    message.p_data = p_in;

    CTC_ERROR_RETURN(_sys_usw_dmps_msg_send_sync_msg(lchip, mcu_id, &message, p_out));

    return CTC_E_NONE;
}

int32 
sys_usw_dmps_msg_send(uint8 lchip, uint8 mcu_id, uint32 msg_type, uint32 data_len, void* p_in)
{
    uint8  priority    = 0;
    uint32 msg_id      = 0;
    uint32 msg_header[DMPS_MSG_HEAD_WORD];
    sys_usw_dmps_mcu_msg_struct_t message = {NULL, NULL};
    sys_dmps_db_msg_handle_t* p_handle = NULL;

#if(1 == SDK_WORK_PLATFORM)
    return CTC_E_NONE;
#endif

#ifdef DMPS_1PP0
    if((16 != mcu_id) && (17 != mcu_id))
    {
        return CTC_E_NONE;
    }
#endif
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_msg_handle(lchip, &p_handle));
    CTC_PTR_VALID_CHECK(p_handle);
    if (!CTC_BMP_ISSET(p_handle->mcu_info.mcu_bmp, mcu_id))
    {
        return CTC_E_NONE;
    }

    CTC_ERROR_RETURN(p_handle->set_header_field((void*)msg_header, SYS_DMPS_MSG_HEADER_TYPE,     msg_type));
    CTC_ERROR_RETURN(p_handle->set_header_field((void*)msg_header, SYS_DMPS_MSG_HEADER_DATA_LEN, data_len));    

    message.header = (void*)msg_header;
    message.p_data = p_in;

    /* fill message id */
    priority = p_handle->registers[msg_type].priority;
    msg_id = p_handle->p_c2m_buf[priority].cur_msg_id;
    CTC_ERROR_RETURN(p_handle->set_header_field(message.header, SYS_DMPS_MSG_HEADER_ID, msg_id));
    p_handle->p_c2m_buf[priority].cur_msg_id = (msg_id + 1) % p_handle->msg_id_num;

    /* write message */
    if (0 == priority)
    {
        DMPS_MSG_HW_LOCK(lchip, (mcu_id / p_handle->mcu_info.core_mcu_num), (mcu_id % p_handle->mcu_info.core_mcu_num));
    }
    CTC_ERROR_RETURN(_sys_usw_dmps_msg_write_async_msg(lchip, mcu_id, priority, &message));
    if (0 == priority)
    {
        DMPS_MSG_HW_UNLOCK(lchip, (mcu_id / p_handle->mcu_info.core_mcu_num), (mcu_id % p_handle->mcu_info.core_mcu_num));
    }
    return CTC_E_NONE;    
}

int32
sys_usw_dmps_msg_recv(uint8 lchip, uint8 mcu_id)
{
    uint8  is_recv_msg      = 0;
    uint8  priority         = 0;
    sys_dmps_db_msg_handle_t* p_handle = NULL;
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_msg_handle(lchip, &p_handle));
    CTC_PTR_VALID_CHECK(p_handle);
    
    CTC_ERROR_RETURN(_sys_usw_dmps_msg_is_recv(lchip, mcu_id, &is_recv_msg, &priority));
    if (is_recv_msg)
    {
        CTC_ERROR_RETURN(_sys_usw_dmps_msg_recv_async_msg(lchip, mcu_id, priority));
    }
    
    return CTC_E_NONE;
}

#define __SYS_DMPS_ANLT_SM_API__

int32
sys_usw_dmps_anlt_sm_send_anlt_en_msg(uint8 lchip, uint16 dport)
{
    uint8  mcu_id           = 0x0;
    uint16 lport            = sys_usw_dmps_db_get_lport_by_dport(lchip, dport);
    dmps_msg_ds_anlt_sm_en_t send_data = {0x0};
    sys_dmps_db_upt_info_t port_info = {0};

    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "lchip", lchip);
    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "dport", dport);
    
    if (NULL == MCHIP_DMPS(lchip)->anlt_sm_get_mcu_id_by_dport)
    {
        return CTC_E_NOT_SUPPORT;
    } 
    CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->anlt_sm_get_mcu_id_by_dport(lchip, dport, &mcu_id));
    
    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_LOGIC_SERDES,   send_data.first_lsd);

#if(1 == SDK_WORK_PLATFORM)
        return CTC_E_NONE;
#endif
    CTC_ERROR_RETURN(sys_usw_dmps_msg_sync_send(lchip, mcu_id, SYS_DMPS_MSG_CODE_SYNC_C2M_ANLT_EN, sizeof(dmps_msg_ds_anlt_sm_en_t), &send_data, NULL));
    sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_AN_EN, 1);

    return CTC_E_NONE;
}

int32
sys_usw_dmps_anlt_sm_send_anlt_timer_en_msg(uint8 lchip, uint32 gport, uint8 enable)
{
    uint8  mcu_id = 0x0;
    uint16 lport  = 0;
    uint16 dport  = 0;
    dmps_msg_ds_anlt_sm_en_t send_data = {0x0};
    sys_dmps_db_upt_info_t port_info   = {0};

    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "lchip", lchip);
    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "dport", dport);

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);
    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));
    
    if (NULL == MCHIP_DMPS(lchip)->anlt_sm_get_mcu_id_by_dport)
    {
        return CTC_E_NOT_SUPPORT;
    } 
    CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->anlt_sm_get_mcu_id_by_dport(lchip, dport, &mcu_id));
    
    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_LOGIC_SERDES, send_data.first_lsd);
    send_data.timer_en = enable ? 1 : 0;

#if(1 == SDK_WORK_PLATFORM)
        return CTC_E_NONE;
#endif
    CTC_ERROR_RETURN(sys_usw_dmps_msg_sync_send(lchip, mcu_id, SYS_DMPS_MSG_CODE_SYNC_C2M_ANLT_TIMER_EN, sizeof(dmps_msg_ds_anlt_sm_en_t), &send_data, NULL));

    return CTC_E_NONE;
}

int32
sys_usw_dmps_anlt_sm_send_restart_an_msg(uint8 lchip, uint16 dport)
{
    uint8  mcu_id           = 0x0;
    dmps_msg_ds_anlt_sm_en_t send_data = {0x0};
    sys_dmps_db_upt_info_t port_info = {0};

    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "lchip", lchip);
    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "dport", dport);
    
    if (NULL == MCHIP_DMPS(lchip)->anlt_sm_get_mcu_id_by_dport)
    {
        return CTC_E_NOT_SUPPORT;
    } 
    CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->anlt_sm_get_mcu_id_by_dport(lchip, dport, &mcu_id));

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_LOGIC_SERDES,   send_data.first_lsd);

    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "dport %d rst AN\n", dport);

#if(1 == SDK_WORK_PLATFORM)
        return CTC_E_NONE;
#endif
    CTC_ERROR_RETURN(sys_usw_dmps_msg_sync_send(lchip, mcu_id, SYS_DMPS_MSG_CODE_SYNC_C2M_RESTART_AN, sizeof(dmps_msg_ds_anlt_sm_en_t), &send_data, NULL));

    return CTC_E_NONE;
}

int32
sys_usw_dmps_anlt_sm_send_link_down_msg(uint8 lchip, uint16 dport, uint8 pcs_status)
{
    uint8  mcu_id           = 0x0;
    dmps_msg_ds_link_down_t send_data = {0x0};
    sys_dmps_db_upt_info_t port_info = {0};

    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "lchip", lchip);
    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "dport", dport);
    
    if (NULL == MCHIP_DMPS(lchip)->anlt_sm_get_mcu_id_by_dport)
    {
        return CTC_E_NOT_SUPPORT;
    } 
    CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->anlt_sm_get_mcu_id_by_dport(lchip, dport, &mcu_id));

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_LOGIC_SERDES,   send_data.first_lsd);
    send_data.pcs_status = pcs_status;

#if(1 == SDK_WORK_PLATFORM)
        return CTC_E_NONE;
#endif
    CTC_ERROR_RETURN(sys_usw_dmps_msg_sync_send(lchip, mcu_id, SYS_DMPS_MSG_CODE_SYNC_C2M_LINK_DOWN_INTR, sizeof(dmps_msg_ds_link_down_t), &send_data, NULL));

    return CTC_E_NONE;
}

int32
sys_usw_dmps_anlt_sm_send_switch_off_msg(uint8 lchip, uint16 dport)
{
    uint8  mcu_id                    = 0x0;
    uint32 speed_value               = 0;
    uint16 lport                     = sys_usw_dmps_db_get_lport_by_dport(lchip, dport);
    sys_dmps_db_upt_info_t port_info = {0};
    dmps_msg_ds_anlt_sm_en_t send_data = {0x0};

    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "lchip", lchip);
    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "dport", dport);

    if (NULL == MCHIP_DMPS(lchip)->anlt_sm_get_mcu_id_by_dport)
    {
        return CTC_E_NOT_SUPPORT;
    }
    CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->anlt_sm_get_mcu_id_by_dport(lchip, dport, &mcu_id));
   
    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PSD_SPEED);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_LOGIC_SERDES,   send_data.first_lsd);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PSD_SPEED, speed_value);
    SYS_USW_SERDES_VALUE_2_SPEED(speed_value, send_data.speed);

#if(1 == SDK_WORK_PLATFORM)
        return CTC_E_NONE;
#endif
    CTC_ERROR_RETURN(sys_usw_dmps_msg_sync_send(lchip, mcu_id, SYS_DMPS_MSG_CODE_SYNC_C2M_ANLT_SM_OFF, sizeof(dmps_msg_ds_anlt_sm_en_t), &send_data, NULL));
    sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_AN_EN, 0);

    return CTC_E_NONE;
}

int32
sys_usw_dmps_anlt_sm_send_an_fec_msg(uint8 lchip, uint16 dport)
{
    uint8  mcu_id           = 0x0;
    dmps_msg_ds_sync_an_fec_t send_data = {0x0};
    sys_dmps_db_upt_info_t port_info       = {0};

    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "lchip", lchip);
    SYS_CL73_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "dport", dport);

    if (NULL == MCHIP_DMPS(lchip)->anlt_sm_get_mcu_id_by_dport)
    {
        return CTC_E_NOT_SUPPORT;
    } 
    CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->anlt_sm_get_mcu_id_by_dport(lchip, dport, &mcu_id));
    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_AN_FEC);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_LOGIC_SERDES,     send_data.first_lsd);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_FEC, send_data.an_fec);

#if(1 == SDK_WORK_PLATFORM)
    return CTC_E_NONE;
#endif  
    CTC_ERROR_RETURN(sys_usw_dmps_msg_sync_send(lchip, mcu_id, SYS_DMPS_MSG_CODE_SYNC_C2M_AN_FEC, sizeof(dmps_msg_ds_sync_an_fec_t), &send_data, NULL));
    
    return CTC_E_NONE;
}

int32
sys_usw_dmps_anlt_sm_cl73_en_event(uint8 lchip, uint16 dport, uint8 enable)
{
    uint8  mac_en = 0;
    uint16 lport  = sys_usw_dmps_db_get_lport_by_dport(lchip, dport);
    sys_dmps_db_upt_info_t port_info = {0};
    
    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_MAC_EN);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_MAC_EN, mac_en);

    if (!mac_en)
    {
        return CTC_E_NONE;
    }

    /* mac_en & anlt_dis -->  mac_en & anlt_en */
    if(enable)
    {
        CTC_ERROR_RETURN(_sys_usw_dmps_set_mac_en(lchip, lport, FALSE, FALSE));
        CTC_ERROR_RETURN(sys_usw_dmps_anlt_sm_send_anlt_en_msg(lchip, dport));
    }
    /* mac_en & anlt_en -->  mac_en & anlt_dis */
    else
    {
        /* mac disable */
        CTC_ERROR_RETURN(_sys_usw_dmps_set_mac_en(lchip, lport, FALSE, FALSE));
        
        CTC_ERROR_RETURN(sys_usw_dmps_anlt_sm_send_switch_off_msg(lchip, dport));
        
        /* mac enable */
        CTC_ERROR_RETURN(_sys_usw_dmps_set_mac_en(lchip, lport, TRUE, FALSE));
    }
    
    return CTC_E_NONE;
}

int32
sys_usw_dmps_anlt_sm_cfg_cl73_ability_event(uint8 lchip, uint16 dport, sys_dmps_an_ability_t* p_cl73_ability)
{    
    uint16 mac_id = 0x0;
    uint32 mac_en = 0x0;
    uint32 an_en  = 0x0;
    uint16 lport  = sys_usw_dmps_db_get_lport_by_dport(lchip, dport);
    
    sys_dmps_db_upt_info_t port_info = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_dport_relative_id(lchip, dport, DMPS_DB_TYPE_MAC, &mac_id));
    
    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_MAC_ID,   mac_id);
    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_EN,   0);
    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_MAC_EN,   0);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_EN, an_en);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_MAC_EN, mac_en);    

    /* If mac_en and an_en, then restart ANLT */
    if (mac_en && an_en)
    {
        CTC_ERROR_RETURN(_sys_usw_dmps_set_mac_en(lchip, lport, FALSE, FALSE));
        CTC_ERROR_RETURN(sys_usw_dmps_anlt_sm_send_restart_an_msg(lchip, dport));
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_AN_RESTART, 2);
    }
    
    return CTC_E_NONE;
}

int32


    /* mac_en & lt_dis -->  mac_en & lt_en */
    /* mac_en & lt_en -->  mac_en & lt_dis */
    

sys_usw_dmps_anlt_sm_register_msg(uint8 lchip)
{
    DMPS_MSG_REGISTER_RX_CB(lchip, SYS_DMPS_MSG_CODE_ASYNC_M2C_ANLT_STATUS_SYNC, _sys_usw_dmps_anlt_sm_msg_recv_cb_status_sync);

    return CTC_E_NONE;
}

